mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-27 07:59:20 +00:00
Merge branch 'master' of git.linphone.org:linphone
This commit is contained in:
commit
983f043b71
147 changed files with 12770 additions and 17091 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -77,3 +77,8 @@ tools/xml2lpc_test
|
|||
coreapi/help/filetransfer
|
||||
tester/receive_file.dump
|
||||
tester/tmp.db
|
||||
.DS_Store
|
||||
Linphone.app
|
||||
*.dmg
|
||||
tester/linphone*.log
|
||||
tester/linphone_log.txt
|
||||
|
|
|
|||
10
.tx/config
Normal file
10
.tx/config
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[main]
|
||||
host = https://www.transifex.com
|
||||
minimum_perc = 1
|
||||
type = PO
|
||||
|
||||
[linphone-gtk.linphonepot]
|
||||
file_filter = po/<lang>.po
|
||||
source_file = po/linphone.pot
|
||||
source_lang = en
|
||||
|
||||
|
|
@ -30,6 +30,8 @@ set(LINPHONE_MICRO_VERSION "0")
|
|||
set(LINPHONE_VERSION "${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}.${LINPHONE_MICRO_VERSION}")
|
||||
set(LINPHONE_SO_VERSION "6")
|
||||
|
||||
set(LINPHONE_ALL_LANGS "cs de es fr he hu it ja nb_NO nl pl pt_BR ru sr sv zh_CN zh_TW")
|
||||
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
|
|
@ -39,9 +41,9 @@ option(ENABLE_DATE "Use build date in internal version number." NO)
|
|||
option(ENABLE_GTK_UI "Turn on or off compilation of gtk interface." YES)
|
||||
option(ENABLE_LDAP "Enable LDAP support." NO)
|
||||
option(ENABLE_MSG_STORAGE "Turn on compilation of message storage." YES)
|
||||
option(ENABLE_NOTIFY "Enable libnotify support." YES)
|
||||
cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI" NO)
|
||||
option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO)
|
||||
option(ENABLE_TOOLS "Turn on or off compilation of console interface" YES)
|
||||
option(ENABLE_TOOLS "Turn on or off compilation of tools." YES)
|
||||
option(ENABLE_TUNNEL "Turn on compilation of tunnel support." NO)
|
||||
option(ENABLE_TUTORIALS "Enable compilation of tutorials." YES)
|
||||
option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES)
|
||||
|
|
@ -50,22 +52,47 @@ option(ENABLE_VIDEO "Build with video support." YES)
|
|||
cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO)
|
||||
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_PREFIX_PATH}/share/cmake/Modules)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_PREFIX_PATH}/share/cmake/Modules")
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
if(MSVC)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_PREFIX_PATH}/include/MSVC)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_PREFIX_PATH}/include/MSVC")
|
||||
endif()
|
||||
|
||||
find_package(BelleSIP REQUIRED)
|
||||
find_package(MS2 REQUIRED)
|
||||
find_package(XML2 REQUIRED)
|
||||
if(ENABLE_UNIT_TESTS)
|
||||
find_package(CUnit)
|
||||
if(CUNIT_FOUND)
|
||||
cmake_push_check_state(RESET)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${CUNIT_INCLUDE_DIRS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CUNIT_LIBRARIES})
|
||||
check_symbol_exists("CU_get_suite" "CUnit/CUnit.h" HAVE_CU_GET_SUITE)
|
||||
check_symbol_exists("CU_curses_run_tests" "CUnit/CUnit.h" HAVE_CU_CURSES)
|
||||
cmake_pop_check_state()
|
||||
else()
|
||||
message(WARNING "Could not find the cunit library!")
|
||||
set(ENABLE_UNIT_TESTS OFF CACHE BOOL "Enable compilation of unit tests." FORCE)
|
||||
endif()
|
||||
endif()
|
||||
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)
|
||||
set(ENABLE_TUNNEL OFF CACHE BOOL "Enable tunnel support." FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_NOTIFY)
|
||||
find_package(Notify)
|
||||
if(NOTIFY_FOUND)
|
||||
set(HAVE_NOTIFY4 1)
|
||||
else()
|
||||
message(WARNING "Could not find the notify library!")
|
||||
set(ENABLE_NOTIFY OFF CACHE BOOL "Enable libnotify support." FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -87,7 +114,29 @@ if(MSVC)
|
|||
include_directories(${CMAKE_PREFIX_PATH}/include/MSVC)
|
||||
endif()
|
||||
|
||||
add_definitions(-DIN_LINPHONE)
|
||||
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wuninitialized -Wdeclaration-after-statement -fno-strict-aliasing -Werror")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Werror")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qunused-arguments -Wno-array-bounds")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -Wno-array-bounds")
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unknown-warning-option -Wno-tautological-compare -Wno-unused-function")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unknown-warning-option -Wno-tautological-compare -Wno-unused-function")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
set(GETTEXT_PACKAGE "linphone")
|
||||
if(ENABLE_RELATIVE_PREFIX)
|
||||
set(LINPHONE_DATA_DIR ".")
|
||||
else()
|
||||
|
|
@ -97,19 +146,33 @@ set(LINPHONE_PLUGINS_DIR "${LINPHONE_DATA_DIR}/lib/liblinphone/plugins")
|
|||
set(PACKAGE_LOCALE_DIR "${LINPHONE_DATA_DIR}/share/locale")
|
||||
set(PACKAGE_DATA_DIR "${LINPHONE_DATA_DIR}/share")
|
||||
set(PACKAGE_SOUND_DIR "${LINPHONE_DATA_DIR}/share/sounds/linphone")
|
||||
set(PACKAGE_RING_DIR "${PACKAGE_SOUND_DIR}/rings")
|
||||
set(PACKAGE_FREEDESKTOP_DIR "${PACKAGE_DATA_DIR}/applications")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/config.h PROPERTIES GENERATED ON)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
|
||||
|
||||
add_subdirectory(coreapi)
|
||||
add_subdirectory(share)
|
||||
if(ENABLE_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
if(ENABLE_VIDEO)
|
||||
add_definitions(-DVIDEO_ENABLED)
|
||||
endif()
|
||||
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/FindLinphone.cmake
|
||||
add_subdirectory(coreapi)
|
||||
add_subdirectory(share)
|
||||
if(ENABLE_GTK_UI)
|
||||
add_subdirectory(gtk)
|
||||
add_subdirectory(pixmaps)
|
||||
endif()
|
||||
if(ENABLE_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
if(ENABLE_UNIT_TESTS)
|
||||
add_subdirectory(tester)
|
||||
endif()
|
||||
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLinphone.cmake
|
||||
DESTINATION share/cmake/Modules
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ PACKAGE_BUNDLE_FILE=$(top_srcdir)/build/macos/$(PACKAGE).bundle
|
|||
EXTRA_DIST = BUGS \
|
||||
README.arm \
|
||||
README.mingw \
|
||||
README.macos \
|
||||
README.macos.md \
|
||||
autogen.sh \
|
||||
linphone.spec \
|
||||
linphone.spec.in \
|
||||
|
|
@ -171,7 +171,7 @@ filelist: zip
|
|||
setup.exe: filelist
|
||||
cp $(ISS_SCRIPT) $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cd $(INSTALLDIR_WITH_PREFIX) && \
|
||||
$(ISCC) $(ISS_SCRIPT)
|
||||
$(ISCC) $(ISS_SCRIPT)
|
||||
mv $(INSTALLDIR_WITH_PREFIX)/Output/setup.exe $(PACKAGE)-$(VERSION)-setup.exe
|
||||
rm -rf $(INSTALLDIR_WITH_PREFIX)/Output
|
||||
rm -f $(INSTALLDIR_WITH_PREFIX)/$(PACKAGE_WIN32_FILELIST)
|
||||
|
|
|
|||
31
README
31
README
|
|
@ -11,12 +11,12 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol.
|
|||
- belle-sip>=1.3.0
|
||||
- speex>=1.2.0 (including libspeexdsp part)
|
||||
- libxml2
|
||||
|
||||
|
||||
+ if you want the gtk/glade interface:
|
||||
- libgtk >=2.16.0
|
||||
+ if you want video support:
|
||||
- libvpx (VP8 codec)
|
||||
- libavcodec (ffmpeg)
|
||||
- libavcodec (ffmpeg)
|
||||
- libswscale (part of ffmpeg too) for better scaling performance
|
||||
- libxv (x11 video extension)
|
||||
- libgl1-mesa (OpenGL API -- GLX development files)
|
||||
|
|
@ -31,7 +31,7 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol.
|
|||
+ if you want uPnP support (optional):
|
||||
- libupnp (version 1.6 branch (not patched with 18-url-upnpstrings.patch))
|
||||
|
||||
Here is the command line to get these dependencies installed for Ubuntu && Debian
|
||||
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 \
|
||||
|
|
@ -43,22 +43,19 @@ libsoup2.4-dev libsqlite3-dev libupnp4-dev
|
|||
|
||||
+ Install srtp (optional) for call encryption :
|
||||
$ git clone git://git.linphone.org/srtp.git
|
||||
$ cd srtp && autoconf && ./configure && make
|
||||
$ sudo make install
|
||||
$ cd srtp && autoconf && ./configure && make
|
||||
$ sudo make install
|
||||
|
||||
+ Install zrtpcpp (optional), for unbreakable call encryption
|
||||
$ sudo apt-get install cmake
|
||||
$ git clone https://github.com/wernerd/ZRTPCPP.git
|
||||
$ cd ZRTPCPP
|
||||
$ cmake -DCORE_LIB=true -DSDES=false . && make
|
||||
$ sudo make install
|
||||
If you get this error: "cc1plus: error: unrecognized command line option ‘-std=c++11’", edit CMakeLists.txt and replace c++11 by c++0x .
|
||||
+ Install zrtp (optional), for unbreakable call encryption
|
||||
$ git clone git://git.linphone.org:bzrtp
|
||||
$ cd bzrtp && ./autogen.sh && ./configure && make
|
||||
$ sudo make install
|
||||
|
||||
- Compile linphone
|
||||
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make && sudo make install
|
||||
$ ./configure
|
||||
$ make && sudo make install
|
||||
$ sudo ldconfig
|
||||
|
||||
|
||||
|
|
@ -71,10 +68,10 @@ For macOS X, see README.macos
|
|||
|
||||
Here is a short description of the content of the source tree.
|
||||
|
||||
- oRTP/ is a poweful implementation of the RTP protocol. See the oRTP/README for more details.
|
||||
- oRTP/ is a poweful implementation of the RTP protocol. See the oRTP/README for more details.
|
||||
It is used by the mediastreamer to send and receive streams to the network.
|
||||
|
||||
- mediastreamer2/ is one of the important part of linphone. It is a framework library for audio
|
||||
- mediastreamer2/ is one of the important part of linphone. It is a framework library for audio
|
||||
and video processing. It contains several objects for grabing audio and video and outputing
|
||||
it (through rtp, to file).
|
||||
It contains also codec objects to compress audio and video streams.
|
||||
|
|
@ -89,6 +86,6 @@ Here is a short description of the content of the source tree.
|
|||
* linphonec.c is the main file for the console version of linphone.
|
||||
* sipomatic.c / sipomatic.h contains the code for sipomatic, the test program that auto-answer to linphone calls.
|
||||
* shell.c (program name: linphonecsh) is a small utilities to send interactive commands to a running linphonec daemon.
|
||||
|
||||
|
||||
- share/ contains translation, documentation, rings and hello sound files.
|
||||
|
||||
|
|
|
|||
146
README.macos
146
README.macos
|
|
@ -1,146 +0,0 @@
|
|||
**********************************
|
||||
* Compiling linphone on macos X *
|
||||
**********************************
|
||||
|
||||
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.
|
||||
|
||||
- In order to enable generation of bundle for multiple macos version and 32 bit processors, it is recommended to:
|
||||
1) edit /opt/local/etc/macports/macports.conf to add the following line:
|
||||
macosx_deployment_target 10.6
|
||||
2) edit /opt/local/etc/macports/variants.conf to add the following line:
|
||||
+universal
|
||||
|
||||
- Install build time dependencies
|
||||
$ 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 libupnp
|
||||
$ sudo port install ffmpeg-devel -gpl2
|
||||
|
||||
- Install gtk. It is recommended to use the quartz backend for better integration.
|
||||
$ sudo port install gtk2 +quartz +no_x11
|
||||
$ sudo port install gtk-osx-application -python27
|
||||
$ sudo port install hicolor-icon-theme
|
||||
|
||||
The next pieces need to be compiled manually. To ensure compatibility with multiple mac os version it is recommended to do:
|
||||
$ export MACOSX_DEPLOYMENT_TARGET=10.6
|
||||
$ export CFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5"
|
||||
$ export OBJCFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5"
|
||||
$ export CXXFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5"
|
||||
$ export LDFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5 -Wl,-headerpad_max_install_names -Wl,-read_only_relocs -Wl,suppress"
|
||||
|
||||
- (Optional) libvpx-1.2 has a bug on macos resulting in ugly video. It is recommended to upgrade it manually to 1.3 from source.
|
||||
The libvpx build isn't able to produce dual architecture files. To workaround this, configure libvpx twice and use lipo to create a dual architecture
|
||||
libvpx.a .
|
||||
|
||||
- Install libantlr3c (library used by belle-sip for parsing)
|
||||
$ git clone -b linphone git://git.linphone.org/antlr3.git
|
||||
$ cd antlr3/runtime/C
|
||||
$ ./autogen.sh
|
||||
$ ./configure --disable-static --prefix=/opt/local && make
|
||||
$ sudo make install
|
||||
|
||||
- Install polarssl (encryption library used by belle-sip)
|
||||
$ git clone git://git.linphone.org/polarssl.git -b linphone
|
||||
$ cd polarssl
|
||||
$ ./autogen.sh && ./configure --prefix=/opt/local && make
|
||||
$ sudo make install
|
||||
|
||||
- Install belle-sip (sip stack)
|
||||
$ git clone git://git.linphone.org/belle-sip.git
|
||||
$ cd belle-sip
|
||||
$ ./autogen.sh && ./configure --prefix=/opt/local && make
|
||||
$ sudo make install
|
||||
|
||||
- Install srtp (optional) for call encryption
|
||||
$ git clone git://git.linphone.org/srtp.git
|
||||
$ cd srtp && autoconf && ./configure --prefix=/opt/local && make libsrtp.a
|
||||
$ sudo make install
|
||||
|
||||
- Install zrtpcpp (optional), for unbreakable call encryption
|
||||
$ sudo port install cmake
|
||||
$ git clone https://github.com/wernerd/ZRTPCPP.git
|
||||
$ cd ZRTPCPP
|
||||
$ cmake -DCORE_LIB=true -DSDES=false CMAKE_INSTALL_NAME_DIR=/usr/local/lib/ -DCMAKE_C_FLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" -DCMAKE_CXX_FLAGS="-arch i386 -arch x86_64 --stdlib=libstdc++ -std=c++11 -lstdc++ -mmacosx-version-min=10.5" -DCMAKE_C_COMPILER=`xcrun --find clang` -DCMAKE_CXX_COMPILER=`xcrun --find clang` .
|
||||
$ sudo make install
|
||||
|
||||
|
||||
- Install gsm codec (optional)
|
||||
$ git clone git://git.linphone.org/gsm.git
|
||||
$ cd gsm
|
||||
$ make CCFLAGS="$CFLAGS -c -O2 -DNeedFunctionPrototypes=1"
|
||||
$ sudo make install INSTALL_ROOT=/opt/local GSM_INSTALL_INC=/opt/local/include
|
||||
|
||||
- Compile and install the tunnel library (optional, proprietary extension only)
|
||||
|
||||
If you got the source code from git, run ./autogen.sh first.
|
||||
Then or otherwise, do:
|
||||
|
||||
$ ./configure --prefix=/opt/local && make && sudo make install
|
||||
|
||||
- Compile linphone
|
||||
|
||||
If you got the source code from git, run ./autogen.sh first.
|
||||
|
||||
Then or otherwise, do:
|
||||
|
||||
$ PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --prefix=/opt/local --with-readline=/opt/local --disable-x11 --with-srtp=/opt/local --with-gsm=/opt/local --enable-zrtp --disable-strict && make
|
||||
|
||||
Install to /opt/local
|
||||
|
||||
$ sudo make install
|
||||
|
||||
Done.
|
||||
|
||||
If you want to generate a portable bundle, then install gtk-mac-bundler.
|
||||
Use git:
|
||||
$ git clone https://github.com/jralls/gtk-mac-bundler.git
|
||||
$ cd gtk-mac-bundler && make install
|
||||
$ export PATH=$PATH:~/.local/bin
|
||||
#make this dummy charset.alias file for the bundler to be happy:
|
||||
$ sudo touch touch /opt/local/lib/charset.alias
|
||||
|
||||
The bundler file in build/macos/linphone.bundle expects some plugins to be installed in /opt/local/lib/mediastreamer/plugins .
|
||||
If you don't need plugins, remove or comment out this line from the bundler file:
|
||||
<binary >
|
||||
${prefix:ms2plugins}/lib/mediastreamer/plugins/*.*.so
|
||||
</binary>
|
||||
|
||||
Then run, inside linphone source tree:
|
||||
Run configure as told before but with "--enable-relativeprefix" appended.
|
||||
$ make
|
||||
$ make bundle
|
||||
|
||||
The resulting bundle is located in linphone build directory, together with a zipped version.
|
||||
|
||||
For a better appearance, you can install the gtk-quartz-engine (a gtk theme) that make gtk application more similar to other mac applications (but not perfect).
|
||||
|
||||
$ git clone https://github.com/jralls/gtk-quartz-engine.git
|
||||
$ cd gtk-quartz-engine
|
||||
$ autoreconf -i
|
||||
$ ./configure --prefix=/opt/local CFLAGS="$CFLAGS -Wno-error" && make
|
||||
$ sudo make install
|
||||
|
||||
Generate a new bundle to have it included.
|
||||
|
||||
libiconv hack
|
||||
*************
|
||||
|
||||
The Makefile.am rules used to generate the bundle fetch a libiconv.2.dylib from a linphone download page.
|
||||
This library adds some additional symbols so that dependencies requiring the iconv from /usr/lib and the ones requiring from the bundle are both satisfied.
|
||||
In case this library needs to generated, here are the commands:
|
||||
$ wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
|
||||
$ cd libiconv-1.14
|
||||
$ patch -p1 < ../linphone/build/macos/libiconv-macos.patch
|
||||
$ ./configure --prefix=/opt/local --disable-static 'CFLAGS=-arch i386 -arch x86_64 -mmacosx-version-min=10.5' 'LDFLAGS=-arch i386 -arch x86_64 -mmacosx-version-min=10.5' CXXFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" && make
|
||||
$ make install DESTDIR=/tmp
|
||||
|
||||
The resulted library can be found in /tmp/opt/local/lib
|
||||
|
||||
|
||||
|
||||
|
||||
171
README.macos.md
Normal file
171
README.macos.md
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
# Compiling Linphone on MacOS X
|
||||
|
||||
## Dependencies
|
||||
|
||||
* Xcode (download from apple or using appstore application)
|
||||
* Java SE
|
||||
* [HomeBrew](http://brew.sh) or [Macports](http://www.macports.org/).
|
||||
|
||||
### Multiple MacOS version support
|
||||
|
||||
In order to enable generation of bundle for multiple MacOS version and 32 bit processors, it is recommended to:
|
||||
|
||||
1. Edit `/opt/local/etc/macports/macports.conf` to add the following line:
|
||||
|
||||
> macosx_deployment_target 10.6
|
||||
|
||||
2. Edit `/opt/local/etc/macports/variants.conf` to add the following line:
|
||||
|
||||
> +universal
|
||||
|
||||
### Build time dependencies
|
||||
|
||||
#### Using MacPorts
|
||||
|
||||
* Linphone core dependencies
|
||||
|
||||
sudo port install automake autoconf libtool intltool wget cunit \
|
||||
antlr3 speex libvpx readline sqlite3 libsoup openldap libupnp \
|
||||
ffmpeg-devel -gpl2
|
||||
|
||||
* UI dependencies: install `GTK`. It is recommended to use the `quartz` backend for better integration.
|
||||
|
||||
sudo port install gtk2 +quartz +no_x11
|
||||
sudo port install gtk-osx-application -python27
|
||||
sudo port install hicolor-icon-theme
|
||||
|
||||
#### Using HomeBrew
|
||||
|
||||
brew install automake intltool libtool pkg-config coreutils \
|
||||
yasm nasm wget imagemagick gettext gtk+ speex ffmpeg pygtk
|
||||
brew link gettext --force
|
||||
# readline is required from linphonec.c otherwise compilation will fail
|
||||
brew link readline --force
|
||||
|
||||
# then you have to install some dependencies from a tap.
|
||||
brew tap Gui13/linphone
|
||||
brew install antlr3.2 libantlr3.4c mattintosh4/gtk-mac-integration/gtk-mac-integration
|
||||
|
||||
### Building Linphone
|
||||
|
||||
The next pieces need to be compiled manually.
|
||||
|
||||
* To ensure compatibility with multiple MacOS versions it is recommended to do:
|
||||
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.6
|
||||
export CFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5"
|
||||
export OBJCFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5"
|
||||
export CXXFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5"
|
||||
export LDFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5 -Wl,-headerpad_max_install_names -Wl,-read_only_relocs -Wl,suppress"
|
||||
|
||||
* Install libantlr3c (library used by belle-sip for parsing)
|
||||
|
||||
git clone -b linphone git://git.linphone.org/antlr3.git
|
||||
cd antlr3/runtime/C
|
||||
./autogen.sh
|
||||
./configure --disable-static --prefix=/opt/local && make
|
||||
sudo make install
|
||||
|
||||
* Install polarssl (encryption library used by belle-sip)
|
||||
|
||||
git clone git://git.linphone.org/polarssl.git -b linphone
|
||||
cd polarssl
|
||||
./autogen.sh && ./configure --prefix=/opt/local && make
|
||||
sudo make install
|
||||
|
||||
* Install belle-sip (sip stack)
|
||||
|
||||
git clone git://git.linphone.org/belle-sip.git
|
||||
cd belle-sip
|
||||
./autogen.sh && ./configure --prefix=/opt/local && make
|
||||
sudo make install
|
||||
|
||||
* (Optional) Install srtp for call encryption
|
||||
|
||||
git clone git://git.linphone.org/srtp.git
|
||||
cd srtp && autoconf && ./configure --prefix=/opt/local && make libsrtp.a
|
||||
sudo make install
|
||||
|
||||
* (Optional) Install zrtp, for unbreakable call encryption
|
||||
|
||||
git clone git://git.linphone.org:bzrtp
|
||||
cd bzrtp && ./autogen.sh && ./configure --prefix=/opt/local && make
|
||||
sudo make install
|
||||
|
||||
* (Optional) Install gsm codec
|
||||
|
||||
git clone git://git.linphone.org/gsm.git
|
||||
cd gsm
|
||||
make CCFLAGS="$CFLAGS -c -O2 -DNeedFunctionPrototypes=1"
|
||||
sudo make install INSTALL_ROOT=/opt/local GSM_INSTALL_INC=/opt/local/include
|
||||
|
||||
* (Optional) libvpx-1.2 has a bug on MacOS resulting in ugly video. It is recommended to upgrade it manually to 1.3 from source.
|
||||
The libvpx build isn't able to produce dual architecture files. To workaround this, configure libvpx twice and use lipo to create a dual architecture `libvpx.a`.
|
||||
|
||||
* (Optional, proprietary extension only) Compile and install the tunnel library
|
||||
If you got the source code from git, run `./autogen.sh` first.
|
||||
Then or otherwise, do:
|
||||
|
||||
./configure --prefix=/opt/local && make && sudo make install
|
||||
|
||||
* Compile Linphone
|
||||
If you got the source code from git, run `./autogen.sh` first.
|
||||
Then or otherwise, :
|
||||
|
||||
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --prefix=/opt/local --disable-x11 --with-srtp=/opt/local --with-gsm=/opt/local --enable-zrtp --disable-strict && make
|
||||
|
||||
* Install on the system
|
||||
|
||||
sudo make install
|
||||
You are done.
|
||||
|
||||
### Generate portable bundle
|
||||
|
||||
If you want to generate a portable bundle, then install `gtk-mac-bundler`:
|
||||
|
||||
git clone https://github.com/jralls/gtk-mac-bundler.git
|
||||
cd gtk-mac-bundler && make install
|
||||
export PATH=$PATH:~/.local/bin
|
||||
#make this dummy charset.alias file for the bundler to be happy:
|
||||
sudo touch /opt/local/lib/charset.alias
|
||||
|
||||
The bundler file in `build/MacOS/linphone.bundle` expects some plugins to be installed in `/opt/local/lib/mediastreamer/plugins`.
|
||||
If you don't need plugins, remove or comment out this line from the bundler file:
|
||||
|
||||
<binary>
|
||||
${prefix:ms2plugins}/lib/mediastreamer/plugins/*.*.so
|
||||
</binary>
|
||||
|
||||
Then run, inside Linphone source tree configure as told before but with `--enable-relativeprefix` appended.
|
||||
|
||||
make && make bundle
|
||||
|
||||
The resulting bundle is located in Linphone build directory, together with a zipped version.
|
||||
|
||||
* For a better appearance, you can install `gtk-quartz-engine` (a GTK theme) that makes GTK application more similar to other Mac applications (but not perfect).
|
||||
|
||||
git clone https://github.com/jralls/gtk-quartz-engine.git
|
||||
cd gtk-quartz-engine
|
||||
autoreconf -i
|
||||
./configure --prefix=/opt/local CFLAGS="$CFLAGS -Wno-error" && make
|
||||
sudo make install
|
||||
|
||||
Generate a new bundle to have it included.
|
||||
|
||||
### libiconv hack
|
||||
|
||||
The `Makefile.am` rules used to generate the bundle fetch a `libiconv.2.dylib` from a Linphone download page.
|
||||
This library adds some additional symbols so that dependencies requiring the `iconv` from `/usr/lib` and the ones requiring from the bundle are both satisfied.
|
||||
In case this library needs to generated, here are the commands:
|
||||
|
||||
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
|
||||
cd libiconv-1.14
|
||||
patch -p1 < ../linphone/build/MacOS/libiconv-MacOS.patch
|
||||
./configure --prefix=/opt/local --disable-static 'CFLAGS=-arch i386 -arch x86_64 -mmacosx-version-min=10.5' 'LDFLAGS=-arch i386 -arch x86_64 -mmacosx-version-min=10.5' CXXFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" && make
|
||||
make install DESTDIR=/tmp
|
||||
|
||||
The resulted library can be found in `/tmp/opt/local/lib`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -22,6 +22,7 @@ if test -f /opt/local/bin/glibtoolize ; then
|
|||
else
|
||||
LIBTOOLIZE=libtoolize
|
||||
fi
|
||||
|
||||
if test -d /opt/local/share/aclocal ; then
|
||||
ACLOCAL_ARGS="-I /opt/local/share/aclocal"
|
||||
fi
|
||||
|
|
@ -30,13 +31,7 @@ if test -d /share/aclocal ; then
|
|||
ACLOCAL_ARGS="$ACLOCAL_ARGS -I /share/aclocal"
|
||||
fi
|
||||
|
||||
if test -f /opt/local/bin/intltoolize ; then
|
||||
#darwin
|
||||
INTLTOOLIZE=/opt/local/bin/intltoolize
|
||||
else
|
||||
#on mingw, it is important to invoke intltoolize with an absolute path to avoid a bug
|
||||
INTLTOOLIZE=/usr/bin/intltoolize
|
||||
fi
|
||||
INTLTOOLIZE=$(which intltoolize)
|
||||
|
||||
echo "Generating build scripts in linphone..."
|
||||
set -x
|
||||
|
|
|
|||
|
|
@ -26,50 +26,51 @@ include $(CLEAR_VARS)
|
|||
LOCAL_CPP_EXTENSION := .cc
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
linphonecore.c \
|
||||
misc.c \
|
||||
enum.c \
|
||||
presence.c \
|
||||
proxy.c \
|
||||
friend.c \
|
||||
authentication.c \
|
||||
lpconfig.c \
|
||||
chat.c \
|
||||
sipsetup.c \
|
||||
siplogin.c \
|
||||
address.c \
|
||||
linphonecore_jni.cc \
|
||||
authentication.c \
|
||||
bellesip_sal/sal_address_impl.c \
|
||||
bellesip_sal/sal_impl.c \
|
||||
bellesip_sal/sal_op_call.c \
|
||||
bellesip_sal/sal_op_call_transfer.c \
|
||||
bellesip_sal/sal_op_events.c \
|
||||
bellesip_sal/sal_op_impl.c \
|
||||
bellesip_sal/sal_op_info.c \
|
||||
bellesip_sal/sal_op_message.c \
|
||||
bellesip_sal/sal_op_presence.c \
|
||||
bellesip_sal/sal_op_registration.c \
|
||||
bellesip_sal/sal_op_publish.c \
|
||||
bellesip_sal/sal_op_info.c \
|
||||
bellesip_sal/sal_op_events.c \
|
||||
bellesip_sal/sal_op_registration.c \
|
||||
bellesip_sal/sal_sdp.c \
|
||||
sal.c \
|
||||
offeranswer.c \
|
||||
callbacks.c \
|
||||
linphonecall.c \
|
||||
conference.c \
|
||||
ec-calibrator.c \
|
||||
linphone_tunnel_config.c \
|
||||
message_storage.c \
|
||||
info.c \
|
||||
event.c \
|
||||
xml.c \
|
||||
xml2lpc.c \
|
||||
lpc2xml.c \
|
||||
remote_provisioning.c \
|
||||
quality_reporting.c \
|
||||
call_log.c \
|
||||
call_params.c \
|
||||
chat.c \
|
||||
conference.c \
|
||||
content.c \
|
||||
ec-calibrator.c \
|
||||
enum.c \
|
||||
event.c \
|
||||
friend.c \
|
||||
info.c \
|
||||
linphonecall.c \
|
||||
linphonecore.c \
|
||||
linphonecore_jni.cc \
|
||||
linphone_tunnel_config.c \
|
||||
localplayer.c \
|
||||
lpc2xml.c \
|
||||
lpconfig.c \
|
||||
message_storage.c \
|
||||
misc.c \
|
||||
offeranswer.c \
|
||||
player.c \
|
||||
fileplayer.c
|
||||
presence.c \
|
||||
proxy.c \
|
||||
quality_reporting.c \
|
||||
remote_provisioning.c \
|
||||
sal.c \
|
||||
siplogin.c \
|
||||
sipsetup.c \
|
||||
xml2lpc.c \
|
||||
xml.c
|
||||
|
||||
ifndef LIBLINPHONE_VERSION
|
||||
LIBLINPHONE_VERSION = "Devel"
|
||||
|
|
@ -256,9 +257,7 @@ LOCAL_EXPORT_CFLAGS := $(LOCAL_CFLAGS)
|
|||
|
||||
ifeq ($(_BUILD_VIDEO),1)
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libavcodec-linphone \
|
||||
libswscale-linphone \
|
||||
libavutil-linphone
|
||||
libffmpeg-linphone
|
||||
endif
|
||||
|
||||
LOCAL_MODULE := liblinphone
|
||||
|
|
@ -266,5 +265,8 @@ LOCAL_MODULE_FILENAME := liblinphone-$(TARGET_ARCH_ABI)
|
|||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
LOCAL_CPPFLAGS=$(LOCAL_CFLAGS)
|
||||
LOCAL_CFLAGS += -Wdeclaration-after-statement
|
||||
|
||||
$(call import-module,android/cpufeatures)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@ common_SRC_FILES := \
|
|||
tester.c \
|
||||
remote_provisioning_tester.c \
|
||||
quality_reporting_tester.c \
|
||||
log_collection_tester.c \
|
||||
transport_tester.c \
|
||||
player_tester.c
|
||||
player_tester.c \
|
||||
dtmf_tester.c
|
||||
|
||||
common_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
|
|
|
|||
|
|
@ -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;$(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>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\belle-sip\include;$(ProjectDir)..\..\oRTP\include;$(ProjectDir)..\..\mediastreamer2\include;$(ProjectDir)..\..\..\tunnel\include;$(ProjectDir)..\..\coreapi;$(ProjectDir)..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\zlib;$(ProjectDir)..\..\..\sqlite\;$(ProjectDir);%(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";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR=".";UNICODE;_XKEYCHECK_H;HAVE_ZLIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
|
|
@ -68,13 +68,16 @@
|
|||
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Outputs>$(TargetDir)$(TargetName)_dll.lib;%(Outputs)</Outputs>
|
||||
</CustomBuildStep>
|
||||
<PreBuildEvent>
|
||||
<Command>version.bat</Command>
|
||||
</PreBuildEvent>
|
||||
<PreBuildEvent>
|
||||
<Message>Batch script to get the git version</Message>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;MSG_STORAGE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
|
@ -82,7 +85,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>NDEBUG;MSG_STORAGE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
|
|
@ -112,6 +115,7 @@
|
|||
<ClCompile Include="..\..\coreapi\callbacks.c" />
|
||||
<ClCompile Include="..\..\coreapi\chat.c" />
|
||||
<ClCompile Include="..\..\coreapi\conference.c" />
|
||||
<ClCompile Include="..\..\coreapi\content.c" />
|
||||
<ClCompile Include="..\..\coreapi\ec-calibrator.c" />
|
||||
<ClCompile Include="..\..\coreapi\enum.c" />
|
||||
<ClCompile Include="..\..\coreapi\event.c" />
|
||||
|
|
@ -121,6 +125,7 @@
|
|||
<ClCompile Include="..\..\coreapi\linphonecore.c" />
|
||||
<ClCompile Include="..\..\coreapi\linphone_tunnel.cc" />
|
||||
<ClCompile Include="..\..\coreapi\linphone_tunnel_config.c" />
|
||||
<ClCompile Include="..\..\coreapi\localplayer.c" />
|
||||
<ClCompile Include="..\..\coreapi\lpconfig.c" />
|
||||
<ClCompile Include="..\..\coreapi\lsd.c" />
|
||||
<ClCompile Include="..\..\coreapi\message_storage.c" />
|
||||
|
|
@ -140,6 +145,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\coreapi\bellesip_sal\sal_impl.h" />
|
||||
<ClInclude Include="..\..\coreapi\content.h" />
|
||||
<ClInclude Include="..\..\coreapi\enum.h" />
|
||||
<ClInclude Include="..\..\coreapi\event.h" />
|
||||
<ClInclude Include="..\..\coreapi\linphonecore.h" />
|
||||
|
|
@ -151,6 +157,8 @@
|
|||
<ClInclude Include="..\..\coreapi\private.h" />
|
||||
<ClInclude Include="..\..\coreapi\sipsetup.h" />
|
||||
<ClInclude Include="..\..\coreapi\xml2lpc.h" />
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="liblinphone_gitversion.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Windows">
|
||||
|
|
@ -189,6 +197,9 @@
|
|||
<ProjectReference Include="..\..\..\mswp8vid\mswp8vid\mswp8vid.vcxproj">
|
||||
<Project>{0565952a-ea62-46a2-8261-f5b4b490da42}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\sqlite\sqlite.vcxproj">
|
||||
<Project>{a45d63b9-60de-476c-8836-f8eedbe139d0}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\tunnel\build\wp8\tunnel\tunnel.vcxproj">
|
||||
<Project>{59500dd1-b192-4ddf-a402-8a8e3739e032}</Project>
|
||||
</ProjectReference>
|
||||
|
|
|
|||
|
|
@ -100,12 +100,15 @@
|
|||
<ClCompile Include="..\..\..\tester\message_tester.c" />
|
||||
<ClCompile Include="..\..\..\tester\presence_tester.c" />
|
||||
<ClCompile Include="..\..\..\tester\quality_reporting_tester.c" />
|
||||
<ClCompile Include="..\..\..\tester\log_collection_tester.c" />
|
||||
<ClCompile Include="..\..\..\tester\register_tester.c" />
|
||||
<ClCompile Include="..\..\..\tester\remote_provisioning_tester.c" />
|
||||
<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="..\..\..\tester\dtmf_tester.c" />
|
||||
|
||||
<ClCompile Include="linphone-tester-native.cpp">
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
|
|
|
|||
22
build/wp8/version.bat
Normal file
22
build/wp8/version.bat
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
@ECHO off
|
||||
|
||||
SET gitlog=
|
||||
FOR /f "delims=" %%a IN ('git log -1 "--pretty=format:%%H" ../../configure.ac') DO SET gitlog=%%a
|
||||
|
||||
IF [%gitlog%] == [] GOTO UnknownGitVersion
|
||||
|
||||
FOR /f "delims=" %%a IN ('git describe --always') DO SET gitdescribe=%%a
|
||||
GOTO End
|
||||
|
||||
:UnknownGitVersion
|
||||
SET gitdescribe=unknown
|
||||
|
||||
:End
|
||||
ECHO #define LIBLINPHONE_GIT_VERSION "%gitdescribe%" > liblinphone_gitversion.h
|
||||
|
||||
|
||||
FOR /F "delims=" %%a IN ('findstr /B AC_INIT ..\..\configure.ac') DO (
|
||||
FOR /F "tokens=1,2,3 delims=[,]" %%1 IN ("%%a") DO (
|
||||
ECHO #define LIBLINPHONE_VERSION "%%3" > config.h
|
||||
)
|
||||
)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
############################################################################
|
||||
# FindLinphone.txt
|
||||
# FindLinphone.cmake
|
||||
# Copyright (C) 2014 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
|
|
@ -33,7 +33,7 @@ find_package(MS2 REQUIRED)
|
|||
find_package(XML2 REQUIRED)
|
||||
find_package(BelleSIP REQUIRED)
|
||||
|
||||
set(_LINPHONEROOT_PATHS
|
||||
set(_LINPHONE_ROOT_PATHS
|
||||
${WITH_LINPHONE}
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
56
cmake/FindNotify.cmake
Normal file
56
cmake/FindNotify.cmake
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
############################################################################
|
||||
# FindNotify.cmake
|
||||
# Copyright (C) 2014 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
# - Find the notify include file and library
|
||||
#
|
||||
# NOTIFY_FOUND - system has linphone
|
||||
# NOTIFY_INCLUDE_DIRS - the linphone include directory
|
||||
# NOTIFY_LIBRARIES - The libraries needed to use linphone
|
||||
|
||||
set(_NOTIFY_ROOT_PATHS
|
||||
${WITH_NOTIFY}
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
|
||||
find_path(NOTIFY_INCLUDE_DIRS
|
||||
NAMES libnotify/notify.h
|
||||
HINTS _NOTIFY_ROOT_PATHS
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
if(NOTIFY_INCLUDE_DIRS)
|
||||
set(HAVE_LIBNOTIFY_NOTIFY_H 1)
|
||||
endif()
|
||||
|
||||
find_library(NOTIFY_LIBRARIES
|
||||
NAMES notify
|
||||
HINTS ${_NOTIFY_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Notify
|
||||
DEFAULT_MSG
|
||||
NOTIFY_INCLUDE_DIRS NOTIFY_LIBRARIES HAVE_LIBNOTIFY_NOTIFY_H
|
||||
)
|
||||
|
||||
mark_as_advanced(NOTIFY_INCLUDE_DIRS NOTIFY_LIBRARIES HAVE_LIBNOTIFY_NOTIFY_H)
|
||||
|
|
@ -26,7 +26,16 @@
|
|||
#define LINPHONE_VERSION "${LINPHONE_VERSION}"
|
||||
#define LIBLINPHONE_VERSION "${LINPHONE_VERSION}"
|
||||
|
||||
#define LINPHONE_ALL_LANGS "${LINPHONE_ALL_LANGS}"
|
||||
|
||||
#define LINPHONE_PLUGINS_DIR "${LINPHONE_PLUGINS_DIR}"
|
||||
|
||||
#define GETTEXT_PACKAGE "${GETTEXT_PACKAGE}"
|
||||
|
||||
#define PACKAGE_LOCALE_DIR "${PACKAGE_LOCALE_DIR}"
|
||||
#define PACKAGE_DATA_DIR "${PACKAGE_DATA_DIR}"
|
||||
#define PACKAGE_SOUND_DIR "${PACKAGE_SOUND_DIR}"
|
||||
|
||||
#cmakedefine HAVE_NOTIFY4
|
||||
#cmakedefine HAVE_CU_GET_SUITE 1
|
||||
#cmakedefine HAVE_CU_CURSES 1
|
||||
|
|
@ -330,7 +330,6 @@ if test "$gtk_ui" = "true" ; then
|
|||
AC_DEFINE([HAVE_NOTIFY1],[1],[NOTIFY1 support])
|
||||
esac
|
||||
else
|
||||
NotifyNotification *n;
|
||||
echo "Libnotify support is disabled."
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ set(SOURCE_FILES
|
|||
authentication.c
|
||||
bellesip_sal/sal_address_impl.c
|
||||
bellesip_sal/sal_impl.c
|
||||
bellesip_sal/sal_impl.h
|
||||
bellesip_sal/sal_op_call.c
|
||||
bellesip_sal/sal_op_call_transfer.c
|
||||
bellesip_sal/sal_op_events.c
|
||||
|
|
@ -46,41 +47,45 @@ set(SOURCE_FILES
|
|||
call_params.c
|
||||
chat.c
|
||||
conference.c
|
||||
contactprovider.c
|
||||
content.c
|
||||
dict.c
|
||||
ec-calibrator.c
|
||||
enum.c
|
||||
enum.h
|
||||
event.c
|
||||
event.h
|
||||
friend.c
|
||||
info.c
|
||||
ldap/ldapprovider.c
|
||||
linphonecall.c
|
||||
linphonecore.c
|
||||
linphonecore.h
|
||||
linphonecore_utils.h
|
||||
linphonefriend.h
|
||||
linphone_tunnel_config.c
|
||||
linphone_tunnel.h
|
||||
localplayer.c
|
||||
lpconfig.c
|
||||
lpconfig.h
|
||||
lsd.c
|
||||
message_storage.c
|
||||
misc.c
|
||||
offeranswer.c
|
||||
offeranswer.h
|
||||
player.c
|
||||
presence.c
|
||||
private.h
|
||||
proxy.c
|
||||
quality_reporting.c
|
||||
remote_provisioning.c
|
||||
sal.c
|
||||
siplogin.c
|
||||
sipsetup.c
|
||||
xml.c
|
||||
xml2lpc.c
|
||||
bellesip_sal/sal_impl.h
|
||||
enum.h
|
||||
event.h
|
||||
linphonecore.h
|
||||
linphonecore_utils.h
|
||||
linphonefriend.h
|
||||
linphone_tunnel.h
|
||||
lpconfig.h
|
||||
offeranswer.h
|
||||
private.h
|
||||
sipsetup.h
|
||||
xml2lpc.c
|
||||
xml2lpc.h
|
||||
xml.c
|
||||
)
|
||||
if(ENABLE_TUNNEL)
|
||||
list(APPEND SOURCE_FILES
|
||||
|
|
@ -101,15 +106,10 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h
|
|||
COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DWORK_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake)
|
||||
|
||||
add_definitions(
|
||||
-DIN_LINPHONE
|
||||
-DUSE_BELLESIP
|
||||
-DLIBLINPHONE_EXPORTS
|
||||
)
|
||||
|
||||
if(ENABLE_VIDEO)
|
||||
add_definitions(-DVIDEO_ENABLED)
|
||||
endif()
|
||||
|
||||
set(LIBS
|
||||
${LIBGCC}
|
||||
${LIBMINGWEX}
|
||||
|
|
@ -152,6 +152,7 @@ install(TARGETS linphone
|
|||
set(HEADER_FILES
|
||||
call_log.h
|
||||
call_params.h
|
||||
content.h
|
||||
event.h
|
||||
linphonecore.h
|
||||
linphonecore_utils.h
|
||||
|
|
|
|||
|
|
@ -24,45 +24,61 @@ 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 call_log.h call_params.h
|
||||
linphone_include_HEADERS=\
|
||||
call_log.h \
|
||||
call_params.h \
|
||||
content.h \
|
||||
event.h \
|
||||
linphonecore.h \
|
||||
linphonecore_utils.h \
|
||||
linphonefriend.h \
|
||||
linphonepresence.h \
|
||||
linphone_tunnel.h \
|
||||
lpc2xml.h \
|
||||
lpconfig.h \
|
||||
sipsetup.h \
|
||||
xml2lpc.h
|
||||
|
||||
lib_LTLIBRARIES=liblinphone.la
|
||||
|
||||
liblinphone_la_SOURCES=\
|
||||
linphonecore.c linphonecore.h private.h\
|
||||
offeranswer.c offeranswer.h\
|
||||
sal.c \
|
||||
callbacks.c \
|
||||
misc.c \
|
||||
address.c \
|
||||
enum.c enum.h \
|
||||
presence.c \
|
||||
proxy.c \
|
||||
friend.c \
|
||||
authentication.c \
|
||||
lpconfig.c lpconfig.h \
|
||||
chat.c \
|
||||
linphonecall.c \
|
||||
sipsetup.c sipsetup.h \
|
||||
siplogin.c \
|
||||
lsd.c linphonecore_utils.h \
|
||||
ec-calibrator.c \
|
||||
conference.c \
|
||||
message_storage.c \
|
||||
info.c \
|
||||
event.c event.h \
|
||||
contactprovider.c contactprovider.h contact_providers_priv.h \
|
||||
ldap/ldapprovider.c ldap/ldapprovider.h \
|
||||
dict.c \
|
||||
xml.c \
|
||||
xml2lpc.c \
|
||||
lpc2xml.c \
|
||||
remote_provisioning.c \
|
||||
quality_reporting.c quality_reporting.h\
|
||||
callbacks.c \
|
||||
call_log.c \
|
||||
call_params.c \
|
||||
chat.c \
|
||||
conference.c \
|
||||
contactprovider.c contactprovider.h contact_providers_priv.h \
|
||||
content.c \
|
||||
dict.c \
|
||||
ec-calibrator.c \
|
||||
enum.c enum.h \
|
||||
event.c event.h \
|
||||
friend.c \
|
||||
info.c \
|
||||
ldap/ldapprovider.c ldap/ldapprovider.h \
|
||||
linphonecall.c \
|
||||
linphonecore.c linphonecore.h \
|
||||
linphonecore_utils.h \
|
||||
localplayer.c \
|
||||
lpc2xml.c \
|
||||
lpconfig.c lpconfig.h \
|
||||
lsd.c \
|
||||
message_storage.c \
|
||||
misc.c \
|
||||
offeranswer.c offeranswer.h\
|
||||
player.c \
|
||||
fileplayer.c \
|
||||
presence.c \
|
||||
private.h \
|
||||
proxy.c \
|
||||
quality_reporting.c quality_reporting.h\
|
||||
remote_provisioning.c \
|
||||
sal.c \
|
||||
siplogin.c \
|
||||
sipsetup.c sipsetup.h \
|
||||
xml2lpc.c \
|
||||
xml.c \
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
if BUILD_UPNP
|
||||
|
|
|
|||
|
|
@ -97,32 +97,16 @@ RtpTransport *TunnelManager::createRtpTransport(int port){
|
|||
|
||||
void TunnelManager::startClient() {
|
||||
ms_message("TunnelManager: Starting tunnel client");
|
||||
if (mTunnelClient == NULL) {
|
||||
mTunnelClient = new TunnelClient();
|
||||
mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this);
|
||||
list<ServerAddr>::iterator it;
|
||||
for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){
|
||||
const ServerAddr &addr=*it;
|
||||
mTunnelClient->addServer(addr.mAddr.c_str(), addr.mPort);
|
||||
}
|
||||
mTunnelClient->setHttpProxy(mHttpProxyHost.c_str(), mHttpProxyPort, mHttpUserName.c_str(), mHttpPasswd.c_str());
|
||||
mTunnelClient = new TunnelClient();
|
||||
mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this);
|
||||
list<ServerAddr>::iterator it;
|
||||
for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){
|
||||
const ServerAddr &addr=*it;
|
||||
mTunnelClient->addServer(addr.mAddr.c_str(), addr.mPort);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
sal_set_tunnel(mCore->sal, mTunnelClient);
|
||||
}
|
||||
|
||||
bool TunnelManager::isConnected() const {
|
||||
|
|
@ -151,9 +135,7 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :
|
|||
mExosipTransport(NULL),
|
||||
#endif
|
||||
mMode(LinphoneTunnelModeDisable),
|
||||
mAutoDetecting(false),
|
||||
mConnecting(false),
|
||||
mScheduledRegistration(false),
|
||||
mState(disabled),
|
||||
mTunnelizeSipPackets(true),
|
||||
mTunnelClient(NULL),
|
||||
mHttpProxyPort(0),
|
||||
|
|
@ -168,7 +150,7 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :
|
|||
mTransportFactories.video_rtcp_func_data=this;
|
||||
mTransportFactories.video_rtp_func=sCreateRtpTransport;
|
||||
mTransportFactories.video_rtp_func_data=this;
|
||||
mVTable = linphone_vtable_new();
|
||||
mVTable = linphone_core_v_table_new();
|
||||
mVTable->network_reachable = networkReachableCb;
|
||||
linphone_core_add_listener(mCore, mVTable);
|
||||
}
|
||||
|
|
@ -177,62 +159,93 @@ TunnelManager::~TunnelManager(){
|
|||
for(UdpMirrorClientList::iterator udpMirror = mUdpMirrorClients.begin(); udpMirror != mUdpMirrorClients.end(); udpMirror++) {
|
||||
udpMirror->stop();
|
||||
}
|
||||
stopClient();
|
||||
if(mTunnelClient) delete mTunnelClient;
|
||||
linphone_core_remove_listener(mCore, mVTable);
|
||||
linphone_vtable_destroy(mVTable);
|
||||
linphone_core_v_table_destroy(mVTable);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
LinphoneProxyConfig* lProxy;
|
||||
linphone_core_get_default_proxy(mCore, &lProxy);
|
||||
if (lProxy) {
|
||||
ms_message("TunnelManager: New registration");
|
||||
lProxy->commit = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelManager::doUnregistration() {
|
||||
LinphoneProxyConfig *lProxy;
|
||||
linphone_core_get_default_proxy(mCore, &lProxy);
|
||||
if(lProxy) {
|
||||
_linphone_proxy_config_unregister(lProxy);
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelManager::processTunnelEvent(const Event &ev){
|
||||
if (ev.mData.mConnected){
|
||||
ms_message("Tunnel is connected");
|
||||
doRegistration();
|
||||
ms_message("TunnelManager: tunnel is connected");
|
||||
if(mState == connecting) {
|
||||
linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories);
|
||||
mState = ready;
|
||||
if(mTunnelizeSipPackets) {
|
||||
doUnregistration();
|
||||
_linphone_core_apply_transports(mCore);
|
||||
doRegistration();
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
ms_error("Tunnel has been disconnected");
|
||||
ms_error("TunnelManager: tunnel has been disconnected");
|
||||
}
|
||||
mConnecting = false;
|
||||
}
|
||||
|
||||
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;
|
||||
if(mMode == mode) return;
|
||||
if((mode==LinphoneTunnelModeDisable && mState==disabled)
|
||||
|| (mode==LinphoneTunnelModeEnable && mState==ready)) {
|
||||
return;
|
||||
}
|
||||
ms_message("TunnelManager: switching mode from %s to %s",
|
||||
tunnel_mode_to_string(mMode),
|
||||
tunnel_mode_to_string(mode));
|
||||
switch(mode) {
|
||||
case LinphoneTunnelModeEnable:
|
||||
if(mState == disabled) {
|
||||
startClient();
|
||||
break;
|
||||
case LinphoneTunnelModeDisable:
|
||||
mState = connecting;
|
||||
mMode = mode;
|
||||
stopClient();
|
||||
doRegistration();
|
||||
break;
|
||||
case LinphoneTunnelModeAuto:
|
||||
mMode = mode;
|
||||
autoDetect();
|
||||
break;
|
||||
default:
|
||||
ms_error("TunnelManager::setMode(): invalid mode (%d)", mode);
|
||||
} else {
|
||||
ms_error("TunnelManager: could not change mode. Bad state");
|
||||
}
|
||||
break;
|
||||
case LinphoneTunnelModeDisable:
|
||||
if(mState == ready) {
|
||||
linphone_core_set_rtp_transport_factories(mCore,NULL);
|
||||
mState = disabled;
|
||||
mMode = mode;
|
||||
if(mTunnelizeSipPackets) {
|
||||
doUnregistration();
|
||||
_linphone_core_apply_transports(mCore);
|
||||
}
|
||||
sal_set_tunnel(mCore->sal,NULL);
|
||||
delete mTunnelClient;
|
||||
mTunnelClient=NULL;
|
||||
} else {
|
||||
ms_error("TunnelManager: could not change mode. Bad state");
|
||||
}
|
||||
break;
|
||||
case LinphoneTunnelModeAuto:
|
||||
if(mState == disabled || mState == ready) {
|
||||
if(startAutoDetection()) {
|
||||
mState = autodetecting;
|
||||
mMode = mode;
|
||||
}
|
||||
} else {
|
||||
ms_error("TunnelManager: could not change mode. Bad state");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ms_error("TunnelManager::setMode(): invalid mode (%d)", mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -244,10 +257,6 @@ 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();
|
||||
|
|
@ -313,22 +322,31 @@ LinphoneTunnelMode TunnelManager::getMode() const {
|
|||
}
|
||||
|
||||
void TunnelManager::processUdpMirrorEvent(const Event &ev){
|
||||
if(mState != autodetecting) return;
|
||||
if (ev.mData.mHaveUdp) {
|
||||
ms_message("TunnelManager: auto detection test succeed");
|
||||
stopClient();
|
||||
doRegistration();
|
||||
mAutoDetecting = false;
|
||||
ms_message("TunnelManager: UDP mirror test succeed");
|
||||
if(mTunnelClient) {
|
||||
if(mTunnelizeSipPackets) doUnregistration();
|
||||
delete mTunnelClient;
|
||||
mTunnelClient = NULL;
|
||||
if(mTunnelizeSipPackets) doRegistration();
|
||||
}
|
||||
mState = disabled;
|
||||
} else {
|
||||
ms_message("TunnelManager: auto detection test failed");
|
||||
ms_message("TunnelManager: UDP mirror test failed");
|
||||
mCurrentUdpMirrorClient++;
|
||||
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
|
||||
ms_message("TunnelManager: trying another udp mirror");
|
||||
ms_message("TunnelManager: trying another UDP mirror");
|
||||
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
|
||||
} else {
|
||||
ms_message("TunnelManager: all auto detection failed. Need ti enable tunnel");
|
||||
startClient();
|
||||
mAutoDetecting = false;
|
||||
ms_message("TunnelManager: all UDP mirror tests failed");
|
||||
if(mTunnelClient==NULL) {
|
||||
startClient();
|
||||
mState = connecting;
|
||||
} else {
|
||||
mState = ready;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -349,24 +367,34 @@ void TunnelManager::sUdpMirrorClientCallback(bool isUdpAvailable, void* data) {
|
|||
|
||||
void TunnelManager::networkReachableCb(LinphoneCore *lc, bool_t reachable) {
|
||||
TunnelManager *tunnel = bcTunnel(linphone_core_get_tunnel(lc));
|
||||
if(reachable && tunnel->getMode() == LinphoneTunnelModeAuto) {
|
||||
tunnel->autoDetect();
|
||||
if(reachable && tunnel->getMode() == LinphoneTunnelModeAuto && tunnel->mState != connecting && tunnel->mState != autodetecting) {
|
||||
tunnel->startAutoDetection();
|
||||
tunnel->mState = autodetecting;
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelManager::autoDetect() {
|
||||
if(mAutoDetecting) {
|
||||
ms_error("TunnelManager: Cannot start auto detection. One auto detection is going on");
|
||||
return;
|
||||
}
|
||||
bool TunnelManager::startAutoDetection() {
|
||||
if (mUdpMirrorClients.empty()) {
|
||||
ms_error("TunnelManager: No UDP mirror server configured aborting auto detection");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
ms_message("TunnelManager: Starting auto-detection");
|
||||
mCurrentUdpMirrorClient = mUdpMirrorClients.begin();
|
||||
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
|
||||
mAutoDetecting = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TunnelManager::isActivated() const{
|
||||
switch(getMode()){
|
||||
case LinphoneTunnelModeAuto:
|
||||
return !(mState==disabled);
|
||||
case LinphoneTunnelModeDisable:
|
||||
return false;
|
||||
case LinphoneTunnelModeEnable:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd) {
|
||||
|
|
@ -376,7 +404,7 @@ void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd
|
|||
}
|
||||
|
||||
void TunnelManager::tunnelizeSipPackets(bool enable){
|
||||
mTunnelizeSipPackets = enable;
|
||||
mTunnelizeSipPackets = enable;
|
||||
}
|
||||
|
||||
bool TunnelManager::tunnelizeSipPacketsEnabled() const {
|
||||
|
|
|
|||
|
|
@ -142,7 +142,15 @@ namespace belledonnecomm {
|
|||
*/
|
||||
bool isConnected() const;
|
||||
|
||||
bool isActivated() const;
|
||||
private:
|
||||
enum State {
|
||||
disabled,
|
||||
connecting,
|
||||
ready,
|
||||
autodetecting
|
||||
};
|
||||
|
||||
enum EventType{
|
||||
UdpMirrorClientEvent,
|
||||
TunnelEvent,
|
||||
|
|
@ -168,9 +176,9 @@ namespace belledonnecomm {
|
|||
private:
|
||||
void onIterate();
|
||||
void doRegistration();
|
||||
void doUnregistration();
|
||||
void startClient();
|
||||
void stopClient();
|
||||
void autoDetect();
|
||||
bool startAutoDetection();
|
||||
void processTunnelEvent(const Event &ev);
|
||||
void processUdpMirrorEvent(const Event &ev);
|
||||
void postEvent(const Event &ev);
|
||||
|
|
@ -178,9 +186,7 @@ namespace belledonnecomm {
|
|||
private:
|
||||
LinphoneCore* mCore;
|
||||
LinphoneTunnelMode mMode;
|
||||
bool mAutoDetecting;
|
||||
bool mConnecting;
|
||||
bool mScheduledRegistration;
|
||||
State mState;
|
||||
bool mTunnelizeSipPackets;
|
||||
TunnelClient* mTunnelClient;
|
||||
std::string mHttpUserName;
|
||||
|
|
@ -194,10 +200,6 @@ namespace belledonnecomm {
|
|||
LinphoneRtpTransportFactories mTransportFactories;
|
||||
Mutex mMutex;
|
||||
std::queue<Event> mEvq;
|
||||
#ifndef USE_BELLESIP
|
||||
TunnelSocket *mSipSocket;
|
||||
eXosip_transport_hooks_t mExosipTransport;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -201,6 +201,37 @@ int linphone_address_get_port(const LinphoneAddress *u) {
|
|||
return sal_address_get_port(u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password encoded in the address.
|
||||
* It is used for basic authentication (not recommended).
|
||||
* @param addr the LinphoneAddress
|
||||
* @param passwd the password to set.
|
||||
**/
|
||||
void linphone_address_set_password(LinphoneAddress *addr, const char *passwd){
|
||||
sal_address_set_password(addr,passwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password encoded in the address.
|
||||
* It is used for basic authentication (not recommended).
|
||||
* @param addr the address
|
||||
* @return the password, if any, NULL otherwise.
|
||||
**/
|
||||
const char *linphone_address_get_password(const LinphoneAddress *addr){
|
||||
return sal_address_get_password(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a header into the address.
|
||||
* Headers appear in the URI with '?', such as <sip:test@linphone.org?SomeHeader=SomeValue>.
|
||||
* @param addr the address
|
||||
* @param header_name the header name
|
||||
* @param header_value the header value
|
||||
**/
|
||||
void linphone_address_set_header(LinphoneAddress *addr, const char *header_name, const char *header_value){
|
||||
sal_address_set_header(addr,header_name,header_value);
|
||||
}
|
||||
|
||||
LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, const char *address) {
|
||||
return linphone_address_new(address);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,10 +39,13 @@ SalAddress * sal_address_clone(const SalAddress *addr){
|
|||
const char *sal_address_get_scheme(const SalAddress *addr){
|
||||
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
|
||||
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
|
||||
belle_generic_uri_t* generic_uri = belle_sip_header_address_get_absolute_uri(header_addr);
|
||||
if (uri) {
|
||||
if (belle_sip_uri_is_secure(uri)) return "sips";
|
||||
else return "sip";
|
||||
} else
|
||||
} else if (generic_uri)
|
||||
return belle_generic_uri_get_scheme(generic_uri);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -114,6 +117,14 @@ void sal_address_set_username(SalAddress *addr, const char *username){
|
|||
SAL_ADDRESS_SET(addr,user,username);
|
||||
}
|
||||
|
||||
void sal_address_set_password(SalAddress *addr, const char *passwd){
|
||||
SAL_ADDRESS_SET(addr,user_password,passwd);
|
||||
}
|
||||
|
||||
const char* sal_address_get_password(const SalAddress *addr){
|
||||
SAL_ADDRESS_GET(addr,user_password);
|
||||
}
|
||||
|
||||
void sal_address_set_domain(SalAddress *addr, const char *host){
|
||||
SAL_ADDRESS_SET(addr,host,host);
|
||||
}
|
||||
|
|
@ -142,10 +153,21 @@ char *sal_address_as_string(const SalAddress *addr){
|
|||
|
||||
char *sal_address_as_string_uri_only(const SalAddress *addr){
|
||||
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
|
||||
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
|
||||
belle_sip_uri_t* sip_uri = belle_sip_header_address_get_uri(header_addr);
|
||||
belle_generic_uri_t* absolute_uri = belle_sip_header_address_get_absolute_uri(header_addr);
|
||||
char tmp[1024]={0};
|
||||
size_t off=0;
|
||||
belle_sip_object_marshal((belle_sip_object_t*)uri,tmp,sizeof(tmp),&off);
|
||||
belle_sip_object_t* uri;
|
||||
|
||||
if (sip_uri) {
|
||||
uri=(belle_sip_object_t*)sip_uri;
|
||||
} else if (absolute_uri) {
|
||||
uri=(belle_sip_object_t*)absolute_uri;
|
||||
} else {
|
||||
ms_error("Cannot generate string for addr [%p] with null uri",addr);
|
||||
return NULL;
|
||||
}
|
||||
belle_sip_object_marshal(uri,tmp,sizeof(tmp),&off);
|
||||
return ms_strdup(tmp);
|
||||
}
|
||||
|
||||
|
|
@ -166,6 +188,10 @@ void sal_address_set_uri_params(SalAddress *addr, const char *params){
|
|||
belle_sip_parameters_set(parameters,params);
|
||||
}
|
||||
|
||||
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value){
|
||||
belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)),header_name, header_value);
|
||||
}
|
||||
|
||||
void sal_address_set_transport(SalAddress* addr,SalTransport transport){
|
||||
if (!sal_address_is_secure(addr)){
|
||||
SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport));
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve
|
|||
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
|
||||
belle_sip_dialog_t* dialog=belle_sip_request_event_get_dialog(event);
|
||||
belle_sip_header_address_t* origin_address;
|
||||
belle_sip_header_address_t* address;
|
||||
belle_sip_header_address_t* address=NULL;
|
||||
belle_sip_header_from_t* from_header;
|
||||
belle_sip_header_to_t* to;
|
||||
belle_sip_response_t* resp;
|
||||
|
|
@ -266,8 +266,14 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve
|
|||
}
|
||||
|
||||
if (!op->base.from_address) {
|
||||
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
|
||||
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
|
||||
if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)))
|
||||
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
|
||||
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
|
||||
else if ((belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header))))
|
||||
address=belle_sip_header_address_create2(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
|
||||
,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header)));
|
||||
else
|
||||
ms_error("Cannot not find from uri from request [%p]",req);
|
||||
sal_op_set_from_address(op,(SalAddress*)address);
|
||||
belle_sip_object_unref(address);
|
||||
}
|
||||
|
|
@ -278,8 +284,15 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve
|
|||
|
||||
if (!op->base.to_address) {
|
||||
to=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_to_t);
|
||||
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to))
|
||||
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to)));
|
||||
if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to)))
|
||||
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to))
|
||||
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to)));
|
||||
else if ((belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(to))))
|
||||
address=belle_sip_header_address_create2(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to))
|
||||
,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(to)));
|
||||
else
|
||||
ms_error("Cannot not find to uri from request [%p]",req);
|
||||
|
||||
sal_op_set_to_address(op,(SalAddress*)address);
|
||||
belle_sip_object_unref(address);
|
||||
}
|
||||
|
|
@ -554,19 +567,29 @@ int sal_transport_available(Sal *sal, SalTransport t){
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
int sal_add_listen_port(Sal *ctx, SalAddress* addr){
|
||||
static int sal_add_listen_port(Sal *ctx, SalAddress* addr, bool_t is_tunneled){
|
||||
int result;
|
||||
belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(ctx->stack,
|
||||
belle_sip_listening_point_t* lp;
|
||||
if (is_tunneled){
|
||||
#ifdef TUNNEL_ENABLED
|
||||
if (sal_address_get_transport(addr)!=SalTransportUDP){
|
||||
ms_error("Tunneled mode is only available for UDP kind of transports.");
|
||||
return -1;
|
||||
}
|
||||
lp = belle_sip_tunnel_listening_point_new(ctx->stack, ctx->tunnel_client);
|
||||
if (!lp){
|
||||
ms_error("Could not create tunnel listening point.");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
ms_error("No tunnel support in library.");
|
||||
return -1;
|
||||
#endif
|
||||
}else{
|
||||
lp = belle_sip_stack_create_listening_point(ctx->stack,
|
||||
sal_address_get_domain(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&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),
|
||||
random_port,
|
||||
sal_transport_to_string(sal_address_get_transport(addr)));
|
||||
}
|
||||
if (lp) {
|
||||
belle_sip_listening_point_set_keep_alive(lp,ctx->keep_alive);
|
||||
|
|
@ -578,13 +601,13 @@ int sal_add_listen_port(Sal *ctx, SalAddress* addr){
|
|||
return result;
|
||||
}
|
||||
|
||||
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure) {
|
||||
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_tunneled) {
|
||||
SalAddress* sal_addr = sal_address_new(NULL);
|
||||
int result;
|
||||
sal_address_set_domain(sal_addr,addr);
|
||||
sal_address_set_port(sal_addr,port);
|
||||
sal_address_set_transport(sal_addr,tr);
|
||||
result = sal_add_listen_port(ctx,sal_addr);
|
||||
result = sal_add_listen_port(ctx, sal_addr, is_tunneled);
|
||||
sal_address_destroy(sal_addr);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -646,43 +669,15 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value){
|
|||
}
|
||||
}
|
||||
}
|
||||
int sal_enable_tunnel(Sal *ctx, void *tunnelclient) {
|
||||
int sal_set_tunnel(Sal *ctx, void *tunnelclient) {
|
||||
#ifdef TUNNEL_ENABLED
|
||||
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);
|
||||
ctx->tunnel_client=tunnelclient;
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
void sal_disable_tunnel(Sal *ctx) {
|
||||
#ifdef TUNNEL_ENABLED
|
||||
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;
|
||||
}
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* returns keepalive period in ms
|
||||
* 0 desactiaved
|
||||
|
|
@ -953,7 +948,7 @@ static void make_supported_header(Sal *sal){
|
|||
char *alltags=NULL;
|
||||
size_t buflen=64;
|
||||
size_t written=0;
|
||||
|
||||
|
||||
if (sal->supported){
|
||||
belle_sip_object_unref(sal->supported);
|
||||
sal->supported=NULL;
|
||||
|
|
@ -1003,7 +998,7 @@ void sal_add_supported_tag(Sal *ctx, const char* tag){
|
|||
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){
|
||||
|
|
@ -1082,6 +1077,10 @@ unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size){
|
|||
return belle_sip_random_bytes(ret,size);
|
||||
}
|
||||
|
||||
char *sal_get_random_token(int size){
|
||||
return belle_sip_random_token(ms_malloc(size),size);
|
||||
}
|
||||
|
||||
unsigned int sal_get_random(void){
|
||||
unsigned int ret=0;
|
||||
belle_sip_random_bytes((unsigned char*)&ret,4);
|
||||
|
|
@ -1101,3 +1100,7 @@ void sal_enable_sip_update_method(Sal *ctx,bool_t value) {
|
|||
ctx->enable_sip_update=value;
|
||||
}
|
||||
|
||||
void sal_default_enable_sdp_removal(Sal *sal, bool_t enable) {
|
||||
if (enable) ms_message("Enabling SDP removal feature by default for all new SalOp in Sal[%p]!", sal);
|
||||
sal->default_sdp_removal = enable;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ 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 *tunnel_client;
|
||||
void *up; /*user pointer*/
|
||||
int session_expires;
|
||||
unsigned int keep_alive;
|
||||
|
|
@ -53,6 +52,7 @@ struct Sal{
|
|||
bool_t enable_test_features;
|
||||
bool_t no_initial_route;
|
||||
bool_t enable_sip_update; /*true by default*/
|
||||
bool_t default_sdp_removal;
|
||||
};
|
||||
|
||||
typedef enum SalOpState {
|
||||
|
|
@ -107,6 +107,7 @@ struct SalOp{
|
|||
bool_t call_released;
|
||||
bool_t manual_refresher;
|
||||
bool_t has_auth_pending;
|
||||
bool_t sdp_removal; /* do not add SDP in outgoing INVITE and remove it from incoming INVITE */
|
||||
int auth_requests; /*number of auth requested for this op*/
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "sal_impl.h"
|
||||
#include "offeranswer.h"
|
||||
|
||||
static int extract_sdp(belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error);
|
||||
static int extract_sdp(SalOp* op,belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error);
|
||||
|
||||
/*used for calls terminated before creation of a dialog*/
|
||||
static void call_set_released(SalOp* op){
|
||||
|
|
@ -41,7 +41,12 @@ static void sdp_process(SalOp *h){
|
|||
ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
|
||||
if (h->result){
|
||||
sal_media_description_unref(h->result);
|
||||
h->result = NULL;
|
||||
}
|
||||
|
||||
/* if SDP was invalid */
|
||||
if (h->base.remote_media == NULL) return;
|
||||
|
||||
h->result=sal_media_description_new();
|
||||
if (h->sdp_offering){
|
||||
offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
|
||||
|
|
@ -75,22 +80,33 @@ static void sdp_process(SalOp *h){
|
|||
static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) {
|
||||
belle_sip_header_content_type_t* content_type ;
|
||||
belle_sip_header_content_length_t* content_length;
|
||||
belle_sip_error_code error = BELLE_SIP_OK;
|
||||
belle_sip_error_code error = BELLE_SIP_BUFFER_OVERFLOW;
|
||||
size_t length = 0;
|
||||
char buff[2048];
|
||||
|
||||
if (session_desc) {
|
||||
size_t bufLen = 2048;
|
||||
size_t hardlimit = 16*1024; /* 16k SDP limit seems reasonable */
|
||||
char* buff = belle_sip_malloc(bufLen);
|
||||
content_type = belle_sip_header_content_type_create("application","sdp");
|
||||
error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,sizeof(buff),&length);
|
||||
if (error != BELLE_SIP_OK) {
|
||||
ms_error("Buffer too small or sdp too big");
|
||||
|
||||
/* try to marshal the description. This could go higher than 2k so we iterate */
|
||||
while( error != BELLE_SIP_OK && bufLen <= hardlimit && buff != NULL){
|
||||
error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length);
|
||||
if( error != BELLE_SIP_OK ){
|
||||
bufLen *= 2;
|
||||
buff = belle_sip_realloc(buff,bufLen);
|
||||
}
|
||||
}
|
||||
/* give up if hard limit reached */
|
||||
if (error != BELLE_SIP_OK || buff == NULL) {
|
||||
ms_error("Buffer too small (%d) or not enough memory, giving up SDP", (int)bufLen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
content_length= belle_sip_header_content_length_create(length);
|
||||
content_length = belle_sip_header_content_length_create(length);
|
||||
belle_sip_message_add_header(msg,BELLE_SIP_HEADER(content_type));
|
||||
belle_sip_message_add_header(msg,BELLE_SIP_HEADER(content_length));
|
||||
belle_sip_message_set_body(msg,buff,length);
|
||||
belle_sip_message_assign_body(msg,buff,length);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
|
|
@ -151,13 +167,14 @@ static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
|
|||
sal_media_description_unref(op->base.remote_media);
|
||||
op->base.remote_media=NULL;
|
||||
}
|
||||
if (extract_sdp(BELLE_SIP_MESSAGE(response),&sdp,&reason)==0) {
|
||||
if (extract_sdp(op,BELLE_SIP_MESSAGE(response),&sdp,&reason)==0) {
|
||||
if (sdp){
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
if (op->base.local_media) sdp_process(op);
|
||||
}/*if no sdp in response, what can we do ?*/
|
||||
}
|
||||
/* process sdp in any case to reset result media description*/
|
||||
if (op->base.local_media) sdp_process(op);
|
||||
}
|
||||
|
||||
static void cancelling_invite(SalOp* op ){
|
||||
|
|
@ -319,7 +336,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
|
|||
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));
|
||||
|
|
@ -367,8 +384,16 @@ static void unsupported_method(belle_sip_server_transaction_t* server_transactio
|
|||
* If body was present is not a SDP or parsing of SDP failed, -1 is returned and SalReason is set appropriately.
|
||||
*
|
||||
**/
|
||||
static int extract_sdp(belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error) {
|
||||
static int extract_sdp(SalOp *op, belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error) {
|
||||
belle_sip_header_content_type_t* content_type=belle_sip_message_get_header_by_type(message,belle_sip_header_content_type_t);
|
||||
|
||||
if (op&&op->sdp_removal){
|
||||
ms_error("Removed willingly SDP because sal_call_enable_sdp_removal was set to TRUE.");
|
||||
*session_desc=NULL;
|
||||
*error=SalReasonNotAcceptable;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (content_type){
|
||||
if (strcmp("application",belle_sip_header_content_type_get_type(content_type))==0
|
||||
&& strcmp("sdp",belle_sip_header_content_type_get_subtype(content_type))==0) {
|
||||
|
|
@ -398,7 +423,7 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
|
|||
belle_sdp_session_description_t* sdp;
|
||||
int err=0;
|
||||
SalReason reason;
|
||||
if (extract_sdp(BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) {
|
||||
if (extract_sdp(op,BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) {
|
||||
if (sdp){
|
||||
op->sdp_offering=FALSE;
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
|
|
@ -473,15 +498,15 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
ms_warning("replace header already set");
|
||||
}
|
||||
|
||||
process_sdp_for_invite(op,req);
|
||||
|
||||
if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) {
|
||||
if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) {
|
||||
op->auto_answer_asked=TRUE;
|
||||
ms_message("The caller asked to automatically answer the call(Emergency?)\n");
|
||||
if (process_sdp_for_invite(op,req) == 0) {
|
||||
if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) {
|
||||
if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) {
|
||||
op->auto_answer_asked=TRUE;
|
||||
ms_message("The caller asked to automatically answer the call(Emergency?)\n");
|
||||
}
|
||||
}
|
||||
op->base.root->callbacks.call_received(op);
|
||||
}
|
||||
op->base.root->callbacks.call_received(op);
|
||||
break;
|
||||
} /* else same behavior as for EARLY state*/
|
||||
}
|
||||
|
|
@ -521,7 +546,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
if (strcmp("ACK",method)==0) {
|
||||
if (op->sdp_offering){
|
||||
SalReason reason;
|
||||
if (extract_sdp(BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){
|
||||
if (extract_sdp(op,BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){
|
||||
if (sdp){
|
||||
if (op->base.remote_media)
|
||||
sal_media_description_unref(op->base.remote_media);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
#include "sal_impl.h"
|
||||
|
||||
|
||||
/*create an operation */
|
||||
SalOp * sal_op_new(Sal *sal){
|
||||
SalOp *op=ms_new0(SalOp,1);
|
||||
|
|
@ -26,6 +25,7 @@ SalOp * sal_op_new(Sal *sal){
|
|||
op->type=SalOpUnknown;
|
||||
op->privacy=SalPrivacyNone;
|
||||
op->manual_refresher=FALSE;/*tells that requests with expiry (SUBSCRIBE, PUBLISH) will be automatically refreshed*/
|
||||
op->sdp_removal=sal->default_sdp_removal;
|
||||
sal_op_ref(op);
|
||||
return op;
|
||||
}
|
||||
|
|
@ -103,6 +103,7 @@ belle_sip_header_contact_t* sal_op_create_contact(SalOp *op){
|
|||
belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact_header),contact_uri);
|
||||
}
|
||||
|
||||
belle_sip_uri_set_user_password(contact_uri,NULL);
|
||||
belle_sip_uri_set_secure(contact_uri,sal_op_is_secure(op));
|
||||
if (op->privacy!=SalPrivacyNone){
|
||||
belle_sip_uri_set_user(contact_uri,NULL);
|
||||
|
|
@ -285,6 +286,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
|
|||
const MSList *elem=sal_op_get_route_addresses(op);
|
||||
const char *transport;
|
||||
const char *method=belle_sip_request_get_method(request);
|
||||
belle_sip_listening_point_t *udplp=belle_sip_provider_get_listening_point(prov,"UDP");
|
||||
|
||||
if (elem) {
|
||||
outbound_proxy=belle_sip_header_address_get_uri((belle_sip_header_address_t*)elem->data);
|
||||
|
|
@ -297,7 +299,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
|
|||
/*compatibility mode: by default it should be udp as not explicitely set and if no udp listening point is available, then use
|
||||
* the first available transport*/
|
||||
if (!belle_sip_uri_is_secure(next_hop_uri)){
|
||||
if (belle_sip_provider_get_listening_point(prov,"UDP")==0){
|
||||
if (udplp==NULL){
|
||||
if (belle_sip_provider_get_listening_point(prov,"TCP")!=NULL){
|
||||
transport="tcp";
|
||||
}else if (belle_sip_provider_get_listening_point(prov,"TLS")!=NULL ){
|
||||
|
|
@ -309,6 +311,13 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
|
|||
belle_sip_uri_set_transport_param(next_hop_uri,transport);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
#ifdef TUNNEL_ENABLED
|
||||
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(udplp,belle_sip_tunnel_listening_point_t)){
|
||||
/* our tunnel mode only supports UDP. Force transport to be set to UDP */
|
||||
belle_sip_uri_set_transport_param(next_hop_uri,"udp");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if ((strcmp(method,"REGISTER")==0 || strcmp(method,"SUBSCRIBE")==0) && transport &&
|
||||
(strcasecmp(transport,"TCP")==0 || strcasecmp(transport,"TLS")==0)){
|
||||
|
|
@ -770,3 +779,7 @@ void sal_op_stop_refreshing(SalOp *op){
|
|||
}
|
||||
}
|
||||
|
||||
void sal_call_enable_sdp_removal(SalOp *h, bool_t enable) {
|
||||
if (enable) ms_message("Enabling SDP removal feature for SalOp[%p]!", h);
|
||||
h->sdp_removal = enable;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *fr
|
|||
|
||||
cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new();
|
||||
cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new();
|
||||
cl->connected_date_time=0;
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ LINPHONE_PUBLIC const char * linphone_call_log_get_call_id(const LinphoneCallLog
|
|||
LINPHONE_PUBLIC LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl);
|
||||
|
||||
/**
|
||||
* Get the duration of the call.
|
||||
* Get the duration of the call since connected.
|
||||
* @param[in] cl LinphoneCallLog object
|
||||
* @return The duration of the call in seconds.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -224,7 +224,8 @@ static bool_t already_a_call_pending(LinphoneCore *lc){
|
|||
|| call->state==LinphoneCallOutgoingInit
|
||||
|| call->state==LinphoneCallOutgoingProgress
|
||||
|| call->state==LinphoneCallOutgoingEarlyMedia
|
||||
|| call->state==LinphoneCallOutgoingRinging){
|
||||
|| call->state==LinphoneCallOutgoingRinging
|
||||
|| call->state==LinphoneCallIdle){ /*case of an incoming call for which ICE candidate gathering is pending.*/
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -234,11 +235,12 @@ static bool_t already_a_call_pending(LinphoneCore *lc){
|
|||
static void call_received(SalOp *h){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
|
||||
LinphoneCall *call;
|
||||
const char *from,*to;
|
||||
char *alt_contact;
|
||||
LinphoneAddress *from_addr, *to_addr;
|
||||
LinphoneAddress *from_addr=NULL;
|
||||
LinphoneAddress *to_addr=NULL;
|
||||
/*this mode is deprcated because probably useless*/
|
||||
bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",FALSE);
|
||||
SalMediaDescription *md;
|
||||
|
||||
/* first check if we can answer successfully to this invite */
|
||||
if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) {
|
||||
|
|
@ -272,10 +274,26 @@ static void call_received(SalOp *h){
|
|||
sal_op_release(h);
|
||||
return;
|
||||
}
|
||||
from=sal_op_get_from(h);
|
||||
to=sal_op_get_to(h);
|
||||
from_addr=linphone_address_new(from);
|
||||
to_addr=linphone_address_new(to);
|
||||
/*in some situation, better to trust the network rather than the UAC*/
|
||||
if (lp_config_get_int(lc->config,"sip","call_logs_use_asserted_id_instead_of_from",0)) {
|
||||
const char * p_asserted_id = sal_custom_header_find(sal_op_get_recv_custom_header(h),"P-Asserted-Identity");
|
||||
LinphoneAddress *p_asserted_id_addr;
|
||||
if (!p_asserted_id) {
|
||||
ms_warning("No P-Asserted-Identity header found so cannot use it for op [%p] instead of from",h);
|
||||
} else {
|
||||
p_asserted_id_addr = linphone_address_new(p_asserted_id);
|
||||
if (!p_asserted_id_addr) {
|
||||
ms_warning("Unsupported P-Asserted-Identity header for op [%p] ",h);
|
||||
} else {
|
||||
ms_message("Using P-Asserted-Identity [%s] instead of from [%s] for op [%p]",p_asserted_id,sal_op_get_from(h),h);
|
||||
from_addr=p_asserted_id_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!from_addr)
|
||||
from_addr=linphone_address_new(sal_op_get_from(h));
|
||||
to_addr=linphone_address_new(sal_op_get_to(h));
|
||||
|
||||
if ((already_a_call_with_remote_address(lc,from_addr) && prevent_colliding_calls) || already_a_call_pending(lc)){
|
||||
ms_warning("Receiving another call while one is ringing or initiated, refusing this one with busy message.");
|
||||
|
|
@ -288,6 +306,17 @@ static void call_received(SalOp *h){
|
|||
|
||||
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
|
||||
|
||||
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){
|
||||
if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){
|
||||
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
|
||||
linphone_call_unref(call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
|
@ -356,6 +385,10 @@ static void call_ringing(SalOp *h){
|
|||
md=sal_call_get_final_media_description(h);
|
||||
if (md==NULL){
|
||||
linphone_core_stop_dtmf_stream(lc);
|
||||
if (call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
/*already doing early media */
|
||||
return;
|
||||
}
|
||||
if (lc->ringstream!=NULL) return;/*already ringing !*/
|
||||
if (lc->sound_conf.play_sndcard!=NULL){
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
|
||||
|
|
@ -395,6 +428,7 @@ 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;
|
||||
bool_t update_state=TRUE;
|
||||
|
||||
if (call==NULL){
|
||||
ms_warning("No call to accept.");
|
||||
|
|
@ -405,7 +439,7 @@ static void call_accepted(SalOp *op){
|
|||
|
||||
/* Handle remote ICE attributes if any. */
|
||||
if (call->ice_session != NULL) {
|
||||
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
|
||||
linphone_call_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
|
||||
}
|
||||
#ifdef BUILD_UPNP
|
||||
if (call->upnp_session != NULL) {
|
||||
|
|
@ -417,12 +451,21 @@ static void call_accepted(SalOp *op){
|
|||
if (md) /*make sure re-invite will not propose video again*/
|
||||
call->params->has_video &= linphone_core_media_description_contains_video_stream(md);
|
||||
|
||||
if (call->state==LinphoneCallOutgoingProgress ||
|
||||
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);
|
||||
switch (call->state){
|
||||
case LinphoneCallOutgoingProgress:
|
||||
case LinphoneCallOutgoingRinging:
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
|
||||
if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
|
||||
break;
|
||||
case LinphoneCallEarlyUpdating:
|
||||
linphone_call_set_state(call,call->prevstate,"Early update accepted");
|
||||
update_state=FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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) ||
|
||||
|
|
@ -435,7 +478,7 @@ static void call_accepted(SalOp *op){
|
|||
ms_free(msg);
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
if (update_state) linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
if (call->refer_pending)
|
||||
linphone_core_start_refered_call(lc,call,NULL);
|
||||
}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
|
||||
|
|
@ -448,7 +491,7 @@ static void call_accepted(SalOp *op){
|
|||
ms_free(msg);
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
if (update_state) linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
}else{
|
||||
if (call->state!=LinphoneCallUpdating){
|
||||
if (call->state==LinphoneCallResuming){
|
||||
|
|
@ -469,13 +512,24 @@ static void call_accepted(SalOp *op){
|
|||
linphone_call_fix_call_parameters(call);
|
||||
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");
|
||||
if (update_state) linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
|
||||
}
|
||||
}else{
|
||||
/*send a bye*/
|
||||
ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
|
||||
linphone_core_abort_call(lc,call,_("Incompatible, check codecs or security settings..."));
|
||||
switch (call->prevstate){
|
||||
/*send a bye only in case of outgoing state*/
|
||||
case LinphoneCallOutgoingInit:
|
||||
case LinphoneCallOutgoingProgress:
|
||||
case LinphoneCallOutgoingRinging:
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
ms_error("Incompatible SDP offer received in 200 OK, need to abort the call");
|
||||
linphone_core_abort_call(lc,call,_("Incompatible, check codecs or security settings..."));
|
||||
break;
|
||||
/*otherwise we are able to resume previous state*/
|
||||
default:
|
||||
ms_message("Incompatible SDP offer received in 200 OK, restoring previous state[%s]",linphone_call_state_to_string(call->prevstate));
|
||||
linphone_call_set_state(call,call->prevstate,_("Incompatible media parameters."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -554,7 +608,8 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
|
|||
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));
|
||||
linphone_call_set_state(call, LinphoneCallEarlyUpdatedByRemote, "EarlyUpdatedByRemote");
|
||||
_linphone_core_accept_call_update(lc,call,NULL,call->prevstate,linphone_call_state_to_string(call->prevstate));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,6 +666,8 @@ static void call_updating(SalOp *op, bool_t is_update){
|
|||
case LinphoneCallRefered:
|
||||
case LinphoneCallError:
|
||||
case LinphoneCallReleased:
|
||||
case LinphoneCallEarlyUpdatedByRemote:
|
||||
case LinphoneCallEarlyUpdating:
|
||||
ms_warning("Receiving reINVITE or UPDATE while in state [%s], should not happen.",linphone_call_state_to_string(call->state));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1113,14 +1170,18 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
|
|||
}
|
||||
|
||||
chat_msg->state=chatStatusSal2Linphone(status);
|
||||
linphone_chat_message_store_state(chat_msg);
|
||||
if (chat_msg && chat_msg->cb) {
|
||||
linphone_chat_message_update_state(chat_msg);
|
||||
|
||||
if (chat_msg && (chat_msg->cb || (chat_msg->callbacks && linphone_chat_message_cbs_get_msg_state_changed(chat_msg->callbacks)))) {
|
||||
ms_message("Notifying text delivery with status %i",chat_msg->state);
|
||||
chat_msg->cb(chat_msg
|
||||
,chat_msg->state
|
||||
,chat_msg->cb_ud);
|
||||
if (chat_msg->callbacks && linphone_chat_message_cbs_get_msg_state_changed(chat_msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(chat_msg->callbacks)(chat_msg, chat_msg->state);
|
||||
} else {
|
||||
/* Legacy */
|
||||
chat_msg->cb(chat_msg,chat_msg->state,chat_msg->cb_ud);
|
||||
}
|
||||
}
|
||||
if (status != SalTextDeliveryInProgress) { /*don't release op if progress*/
|
||||
if (status != SalTextDeliveryInProgress) { /*only release op if not in progress*/
|
||||
linphone_chat_message_destroy(chat_msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -1151,14 +1212,13 @@ 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={0};
|
||||
|
||||
if (lev==NULL) {
|
||||
/*out of subscribe notify */
|
||||
lev=linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname);
|
||||
}
|
||||
{
|
||||
const LinphoneContent *ct=linphone_content_from_sal_body(&content,body);
|
||||
LinphoneContent *ct=linphone_content_from_sal_body(body);
|
||||
if (ct) linphone_core_notify_notify_received(lc,lev,eventname,ct);
|
||||
}
|
||||
if (st!=SalSubscribeNone){
|
||||
|
|
|
|||
389
coreapi/chat.c
389
coreapi/chat.c
|
|
@ -35,22 +35,159 @@
|
|||
#define COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT 120
|
||||
|
||||
|
||||
static LinphoneChatMessageCbs * linphone_chat_message_cbs_new(void) {
|
||||
return belle_sip_object_new(LinphoneChatMessageCbs);
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatMessageCbs);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatMessageCbs, belle_sip_object_t,
|
||||
NULL, // destroy
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
FALSE
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup chatroom
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Acquire a reference to the LinphoneChatMessageCbs object.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The same LinphoneChatMessageCbs object.
|
||||
*/
|
||||
LinphoneChatMessageCbs * linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs) {
|
||||
belle_sip_object_ref(cbs);
|
||||
return cbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release reference to the LinphoneChatMessageCbs object.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
*/
|
||||
void linphone_chat_message_cbs_unref(LinphoneChatMessageCbs *cbs) {
|
||||
belle_sip_object_unref(cbs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the user pointer associated with the LinphoneChatMessageCbs object.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The user pointer associated with the LinphoneChatMessageCbs object.
|
||||
*/
|
||||
void *linphone_chat_message_cbs_get_user_data(const LinphoneChatMessageCbs *cbs) {
|
||||
return cbs->user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a user pointer to the LinphoneChatMessageCbs object.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @param[in] ud The user pointer to associate with the LinphoneChatMessageCbs object.
|
||||
*/
|
||||
void linphone_chat_message_cbs_set_user_data(LinphoneChatMessageCbs *cbs, void *ud) {
|
||||
cbs->user_data = ud;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message state changed callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The current message state changed callback.
|
||||
*/
|
||||
LinphoneChatMessageMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs) {
|
||||
return cbs->msg_state_changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the message state changed callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @param[in] cb The message state changed callback to be used.
|
||||
*/
|
||||
void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageMsgStateChangedCb cb) {
|
||||
cbs->msg_state_changed = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file transfer receive callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The current file transfer receive callback.
|
||||
*/
|
||||
LinphoneChatMessageFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs) {
|
||||
return cbs->file_transfer_recv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file transfer receive callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @param[in] cb The file transfer receive callback to be used.
|
||||
*/
|
||||
void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageFileTransferRecvCb cb) {
|
||||
cbs->file_transfer_recv = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file transfer send callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The current file transfer send callback.
|
||||
*/
|
||||
LinphoneChatMessageFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs) {
|
||||
return cbs->file_transfer_send;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file transfer send callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @param[in] cb The file transfer send callback to be used.
|
||||
*/
|
||||
void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageFileTransferSendCb cb) {
|
||||
cbs->file_transfer_send = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file transfer progress indication callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The current file transfer progress indication callback.
|
||||
*/
|
||||
LinphoneChatMessageFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs) {
|
||||
return cbs->file_transfer_progress_indication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file transfer progress indication callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @param[in] cb The file transfer progress indication callback to be used.
|
||||
*/
|
||||
void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageFileTransferProgressIndicationCb cb) {
|
||||
cbs->file_transfer_progress_indication = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg);
|
||||
#define MULTIPART_BOUNDARY "---------------------------14737809831466499882746641449"
|
||||
const char *multipart_boundary=MULTIPART_BOUNDARY;
|
||||
|
||||
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]", 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);
|
||||
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateNotDelivered);
|
||||
}
|
||||
}
|
||||
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]", 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);
|
||||
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateNotDelivered);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,14 +195,20 @@ static void process_io_error_download(void *data, const belle_sip_io_error_event
|
|||
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
|
||||
ms_error("I/O Error during file download %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room);
|
||||
if (msg->cb) {
|
||||
msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->chat_room->lc);
|
||||
msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateFileTransferError);
|
||||
}
|
||||
}
|
||||
static void process_auth_requested_download(void *data, belle_sip_auth_event_t *event){
|
||||
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
|
||||
ms_error("Error during file download : auth requested to get %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room);
|
||||
if (msg->cb) {
|
||||
msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->chat_room->lc);
|
||||
msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateFileTransferError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,10 +218,12 @@ static void process_auth_requested_download(void *data, belle_sip_auth_event_t *
|
|||
*/
|
||||
static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, size_t total){
|
||||
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
|
||||
LinphoneCore *lc = chatMsg->chat_room->lc;
|
||||
/* call back given by application level */
|
||||
linphone_core_notify_file_transfer_progress_indication(lc, chatMsg, chatMsg->file_transfer_information, (size_t)(((double)offset/(double)total)*100.0));
|
||||
return;
|
||||
if (linphone_chat_message_cbs_get_file_transfer_progress_indication(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_progress_indication(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, total);
|
||||
} else {
|
||||
/* Legacy: call back given by application level */
|
||||
linphone_core_notify_file_transfer_progress_indication(chatMsg->chat_room->lc, chatMsg, chatMsg->file_transfer_information, offset, total);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,9 +243,14 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_
|
|||
char *buf = (char *)buffer;
|
||||
|
||||
/* if we've not reach the end of file yet, ask for more data*/
|
||||
if (offset<chatMsg->file_transfer_information->size){
|
||||
if (offset<linphone_content_get_size(chatMsg->file_transfer_information)){
|
||||
/* get data from call back */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
} else {
|
||||
/* Legacy */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
return BELLE_SIP_CONTINUE;
|
||||
|
|
@ -128,35 +278,33 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
belle_http_request_t *req;
|
||||
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;
|
||||
belle_sip_body_handler_t *first_part_bh;
|
||||
|
||||
/* 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);
|
||||
first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", linphone_content_get_name(msg->file_transfer_information));
|
||||
|
||||
/* 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));
|
||||
if (msg->file_transfer_filepath != NULL) {
|
||||
first_part_bh=(belle_sip_body_handler_t *)belle_sip_file_body_handler_new(msg->file_transfer_filepath,NULL,msg);
|
||||
} else {
|
||||
first_part_bh=(belle_sip_body_handler_t *)belle_sip_user_body_handler_new(linphone_content_get_size(msg->file_transfer_information),NULL,NULL,linphone_chat_message_file_transfer_on_send_body,msg);
|
||||
}
|
||||
belle_sip_body_handler_add_header(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_body_handler_add_header(first_part_bh, (belle_sip_header_t *)belle_sip_header_content_type_create(linphone_content_get_type(msg->file_transfer_information), linphone_content_get_subtype(msg->file_transfer_information)));
|
||||
|
||||
/* insert it in a multipart body handler which will manage the boundaries of multipart message */
|
||||
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, first_part_bh);
|
||||
|
||||
/* create the http request: do not include the message header at this point, it is done by bellesip when setting the multipart body handler in the message */
|
||||
ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version());
|
||||
|
||||
content_type=belle_sip_strdup_printf("multipart/form-data; boundary=%s",multipart_boundary);
|
||||
|
||||
uri=belle_generic_uri_parse(linphone_core_get_file_transfer_server(msg->chat_room->lc));
|
||||
|
||||
req=belle_http_request_create("POST",
|
||||
uri,
|
||||
belle_sip_header_create("User-Agent",ua),
|
||||
belle_sip_header_create("Content-type",content_type),
|
||||
NULL);
|
||||
ms_free(ua);
|
||||
belle_sip_free(content_type);
|
||||
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req),BELLE_SIP_BODY_HANDLER(bh));
|
||||
cbs.process_response=linphone_chat_message_process_response_from_post_file;
|
||||
cbs.process_io_error=process_io_error_upload;
|
||||
|
|
@ -174,6 +322,12 @@ 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);
|
||||
msg->content_type = ms_strdup("application/vnd.gsma.rcs-ft-http+xml");
|
||||
if (msg->cb) {
|
||||
msg->cb(msg, LinphoneChatMessageStateFileTransferDone, msg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateFileTransferDone);
|
||||
}
|
||||
_linphone_chat_room_send_message(msg->chat_room, msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -495,6 +649,17 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
|
|||
linphone_chat_message_unref(msg);
|
||||
}
|
||||
|
||||
void linphone_chat_message_update_state(LinphoneChatMessage* chat_msg ) {
|
||||
linphone_chat_message_store_state(chat_msg);
|
||||
|
||||
if( chat_msg->state == LinphoneChatMessageStateDelivered
|
||||
|| chat_msg->state == LinphoneChatMessageStateNotDelivered ){
|
||||
// message is not transient anymore, we can remove it from our transient list and unref it :
|
||||
chat_msg->chat_room->transient_messages = ms_list_remove(chat_msg->chat_room->transient_messages, chat_msg);
|
||||
linphone_chat_message_unref(chat_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to peer member of this chat room.
|
||||
* @deprecated linphone_chat_room_send_message2() gives more control on the message expedition.
|
||||
|
|
@ -506,9 +671,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 (msg->message){
|
||||
/*legacy API*/
|
||||
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);
|
||||
|
|
@ -517,20 +683,13 @@ void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc,
|
|||
void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *sal_msg){
|
||||
LinphoneChatRoom *cr=NULL;
|
||||
LinphoneAddress *addr;
|
||||
char *cleanfrom;
|
||||
char *from;
|
||||
LinphoneChatMessage* msg;
|
||||
const SalCustomHeader *ch;
|
||||
|
||||
addr=linphone_address_new(sal_msg->from);
|
||||
linphone_address_clean(addr);
|
||||
cr=linphone_core_get_chat_room(lc,addr);
|
||||
cleanfrom=linphone_address_as_string(addr);
|
||||
from=linphone_address_as_string_uri_only(addr);
|
||||
if (cr==NULL){
|
||||
/* create a new chat room */
|
||||
cr=linphone_core_create_chat_room(lc,cleanfrom);
|
||||
}
|
||||
|
||||
if (sal_msg->content_type != NULL) { /* content_type field is, for now, used only for rcs file transfer but we shall strcmp it with "application/vnd.gsma.rcs-ft-http+xml" */
|
||||
xmlChar *file_url = NULL;
|
||||
xmlDocPtr xmlMessageBody;
|
||||
|
|
@ -538,8 +697,7 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
|
||||
msg = linphone_chat_room_create_message(cr, NULL); /* create a message with empty body */
|
||||
msg->content_type = ms_strdup(sal_msg->content_type); /* add the content_type "application/vnd.gsma.rcs-ft-http+xml" */
|
||||
msg->file_transfer_information = (LinphoneContent *)malloc(sizeof(LinphoneContent));
|
||||
memset(msg->file_transfer_information, 0, sizeof(*(msg->file_transfer_information)));
|
||||
msg->file_transfer_information = linphone_content_new();
|
||||
|
||||
/* parse the message body to get all informations from it */
|
||||
xmlMessageBody = xmlParseDoc((const xmlChar *)sal_msg->text);
|
||||
|
|
@ -555,21 +713,27 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
while (cur!=NULL) {
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *)"file-size")) {
|
||||
xmlChar *fileSizeString = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1);
|
||||
msg->file_transfer_information->size = strtol((const char*)fileSizeString, NULL, 10);
|
||||
linphone_content_set_size(msg->file_transfer_information, strtol((const char*)fileSizeString, NULL, 10));
|
||||
xmlFree(fileSizeString);
|
||||
}
|
||||
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) {
|
||||
msg->file_transfer_information->name = (char *)xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1);
|
||||
linphone_content_set_name(msg->file_transfer_information, (const char *)xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1));
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *)"content-type")) {
|
||||
xmlChar *contentType = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1);
|
||||
int contentTypeIndex = 0;
|
||||
char *type;
|
||||
char *subtype;
|
||||
while (contentType[contentTypeIndex]!='/' && contentType[contentTypeIndex]!='\0') {
|
||||
contentTypeIndex++;
|
||||
}
|
||||
msg->file_transfer_information->type = ms_strndup((char *)contentType, contentTypeIndex);
|
||||
msg->file_transfer_information->subtype = ms_strdup(((char *)contentType+contentTypeIndex+1));
|
||||
type = ms_strndup((char *)contentType, contentTypeIndex);
|
||||
subtype = ms_strdup(((char *)contentType+contentTypeIndex+1));
|
||||
linphone_content_set_type(msg->file_transfer_information, type);
|
||||
linphone_content_set_subtype(msg->file_transfer_information, subtype);
|
||||
ms_free(subtype);
|
||||
ms_free(type);
|
||||
xmlFree(contentType);
|
||||
}
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) {
|
||||
|
|
@ -616,8 +780,6 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
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);
|
||||
}
|
||||
|
||||
static int linphone_chat_room_remote_refresh_composing_expired(void *data, unsigned int revents) {
|
||||
|
|
@ -729,6 +891,7 @@ const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr)
|
|||
*/
|
||||
LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr, const char* message) {
|
||||
LinphoneChatMessage* msg = belle_sip_object_new(LinphoneChatMessage);
|
||||
msg->callbacks=linphone_chat_message_cbs_new();
|
||||
msg->chat_room=(LinphoneChatRoom*)cr;
|
||||
msg->message=message?ms_strdup(message):NULL;
|
||||
msg->is_read=TRUE;
|
||||
|
|
@ -755,6 +918,7 @@ LinphoneChatMessage* linphone_chat_room_create_message_2(
|
|||
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
|
||||
|
||||
LinphoneChatMessage* msg = belle_sip_object_new(LinphoneChatMessage);
|
||||
msg->callbacks=linphone_chat_message_cbs_new();
|
||||
msg->chat_room=(LinphoneChatRoom*)cr;
|
||||
msg->message=message?ms_strdup(message):NULL;
|
||||
msg->external_body_url=external_body_url?ms_strdup(external_body_url):NULL;
|
||||
|
|
@ -781,6 +945,7 @@ LinphoneChatMessage* linphone_chat_room_create_message_2(
|
|||
* @param msg #LinphoneChatMessage message to be sent
|
||||
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when message is delivered or could not be delivered. May be NULL
|
||||
* @param ud user data for the status cb.
|
||||
* @deprecated Use linphone_chat_room_send_chat_message() instead.
|
||||
* @note The LinphoneChatMessage must not be destroyed until the the callback is called.
|
||||
*/
|
||||
void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb, void* ud) {
|
||||
|
|
@ -790,6 +955,18 @@ void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage*
|
|||
_linphone_chat_room_send_message(cr, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to peer member of this chat room.
|
||||
* @param[in] cr LinphoneChatRoom object
|
||||
* @param[in] msg LinphoneChatMessage object
|
||||
* The state of the message sending will be notified via the callbacks defined in the LinphoneChatMessageCbs object that can be obtained
|
||||
* by calling linphone_chat_message_get_callbacks().
|
||||
*/
|
||||
void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
msg->state = LinphoneChatMessageStateInProgress;
|
||||
_linphone_chat_room_send_message(cr, msg);
|
||||
}
|
||||
|
||||
static char * linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) {
|
||||
xmlBufferPtr buf;
|
||||
xmlTextWriterPtr writer;
|
||||
|
|
@ -1027,35 +1204,38 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
|
|||
if (chatMsg->http_request == NULL) {
|
||||
return;
|
||||
}
|
||||
/* call back given by application level */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
|
||||
if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
|
||||
} else {
|
||||
/* Legacy: call back given by application level */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static LinphoneContent* linphone_chat_create_file_transfer_information_from_headers(const belle_sip_message_t* message ){
|
||||
LinphoneContent *content = ms_malloc0(sizeof(LinphoneContent));
|
||||
LinphoneContent *content = linphone_content_new();
|
||||
|
||||
belle_sip_header_content_length_t* content_length_hdr = BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(message, "Content-Length"));
|
||||
belle_sip_header_content_type_t* content_type_hdr = BELLE_SIP_HEADER_CONTENT_TYPE(belle_sip_message_get_header(message, "Content-Type"));
|
||||
const char* type = NULL,*subtype = NULL;
|
||||
|
||||
content->name = ms_strdup("");
|
||||
linphone_content_set_name(content, "");
|
||||
|
||||
if( content_type_hdr ){
|
||||
type = belle_sip_header_content_type_get_type(content_type_hdr);
|
||||
subtype = belle_sip_header_content_type_get_subtype(content_type_hdr);
|
||||
ms_message("Extracted content type %s / %s from header", type?type:"", subtype?subtype:"");
|
||||
if( type ) content->type = ms_strdup(type);
|
||||
if( subtype ) content->type = ms_strdup(subtype);
|
||||
if( type ) linphone_content_set_type(content, type);
|
||||
if( subtype ) linphone_content_set_subtype(content, subtype);
|
||||
}
|
||||
|
||||
if( content_length_hdr ){
|
||||
content->size = belle_sip_header_content_length_get_content_length(content_length_hdr);
|
||||
ms_message("Extracted content length %i from header", (int)content->size);
|
||||
linphone_content_set_size(content, belle_sip_header_content_length_get_content_length(content_length_hdr));
|
||||
ms_message("Extracted content length %i from header", (int)linphone_content_get_size(content));
|
||||
}
|
||||
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
|
@ -1073,19 +1253,24 @@ static void linphone_chat_process_response_headers_from_get_file(void *data, con
|
|||
}
|
||||
|
||||
if( message->file_transfer_information ){
|
||||
body_size = message->file_transfer_information->size;
|
||||
body_size = linphone_content_get_size(message->file_transfer_information);
|
||||
}
|
||||
|
||||
belle_sip_message_set_body_handler(
|
||||
(belle_sip_message_t*)event->response,
|
||||
(belle_sip_body_handler_t*)belle_sip_user_body_handler_new(body_size, linphone_chat_message_file_transfer_on_progress,on_recv_body,NULL,message)
|
||||
);
|
||||
if (message->file_transfer_filepath == NULL) {
|
||||
belle_sip_message_set_body_handler(
|
||||
(belle_sip_message_t*)event->response,
|
||||
(belle_sip_body_handler_t*)belle_sip_user_body_handler_new(body_size, linphone_chat_message_file_transfer_on_progress,on_recv_body,NULL,message)
|
||||
);
|
||||
} else {
|
||||
belle_sip_message_set_body_handler(
|
||||
(belle_sip_message_t *)event->response,
|
||||
(belle_sip_body_handler_t *)belle_sip_file_body_handler_new(message->file_transfer_filepath, linphone_chat_message_file_transfer_on_progress, message)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_chat_process_response_from_get_file(void *data, const belle_http_response_event_t *event){
|
||||
//LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
|
||||
|
||||
/* check the answer code */
|
||||
if (event->response){
|
||||
int code=belle_http_response_get_status_code(event->response);
|
||||
|
|
@ -1093,18 +1278,26 @@ 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 */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
|
||||
if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, NULL, 0);
|
||||
} else {
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
|
||||
}
|
||||
if (chatMsg->cb) {
|
||||
chatMsg->cb(chatMsg, LinphoneChatMessageStateFileTransferDone, chatMsg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(chatMsg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(chatMsg->callbacks)(chatMsg, LinphoneChatMessageStateFileTransferDone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the download of the file from remote server
|
||||
*
|
||||
* @param message #LinphoneChatMessage
|
||||
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded
|
||||
* Start the download of the file referenced in a LinphoneChatMessage from remote server.
|
||||
* @param[in] message LinphoneChatMessage object.
|
||||
*/
|
||||
void linphone_chat_message_start_file_download(LinphoneChatMessage *message, LinphoneChatMessageStateChangedCb status_cb) {
|
||||
void linphone_chat_message_download_file(LinphoneChatMessage *message) {
|
||||
belle_http_request_listener_callbacks_t cbs={0};
|
||||
belle_http_request_listener_t *l;
|
||||
belle_generic_uri_t *uri;
|
||||
|
|
@ -1128,22 +1321,37 @@ void linphone_chat_message_start_file_download(LinphoneChatMessage *message, Lin
|
|||
l=belle_http_request_listener_create_from_callbacks(&cbs, (void *)message);
|
||||
belle_sip_object_data_set(BELLE_SIP_OBJECT(req),"message",(void *)message,NULL);
|
||||
message->http_request = req; /* keep a reference on the request to be able to cancel the download */
|
||||
message->cb = status_cb;
|
||||
message->state = LinphoneChatMessageStateInProgress; /* start the download, status is In Progress */
|
||||
belle_http_provider_send_request(message->chat_room->lc->http_provider,req,l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the download of the file from remote server
|
||||
*
|
||||
* @param message #LinphoneChatMessage
|
||||
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded
|
||||
* @deprecated Use linphone_chat_message_download_file() instead.
|
||||
*/
|
||||
void linphone_chat_message_start_file_download(LinphoneChatMessage *message, LinphoneChatMessageStateChangedCb status_cb, void *ud) {
|
||||
message->cb = status_cb;
|
||||
message->cb_ud = ud;
|
||||
linphone_chat_message_download_file(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel an ongoing file transfer attached to this message.(upload or download)
|
||||
* @param msg #LinphoneChatMessage
|
||||
*/
|
||||
void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage *msg) {
|
||||
void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage *msg) {
|
||||
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;
|
||||
if (msg->cb) {
|
||||
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
|
||||
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->cb_ud);
|
||||
}
|
||||
if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) {
|
||||
linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateNotDelivered);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1294,6 +1502,7 @@ LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg)
|
|||
new_message->state=msg->state;
|
||||
new_message->storage_id=msg->storage_id;
|
||||
if (msg->from) new_message->from=linphone_address_clone(msg->from);
|
||||
if (msg->file_transfer_filepath) new_message->file_transfer_filepath=ms_strdup(msg->file_transfer_filepath);
|
||||
return new_message;
|
||||
}
|
||||
|
||||
|
|
@ -1318,9 +1527,12 @@ static void _linphone_chat_message_destroy(LinphoneChatMessage* msg) {
|
|||
if (msg->custom_headers) sal_custom_header_free(msg->custom_headers);
|
||||
if (msg->content_type) ms_free(msg->content_type);
|
||||
if (msg->file_transfer_information) {
|
||||
linphone_content_uninit(msg->file_transfer_information);
|
||||
ms_free(msg->file_transfer_information);
|
||||
linphone_content_unref(msg->file_transfer_information);
|
||||
}
|
||||
if (msg->file_transfer_filepath != NULL) {
|
||||
ms_free(msg->file_transfer_filepath);
|
||||
}
|
||||
linphone_chat_message_cbs_unref(msg->callbacks);
|
||||
ms_message("LinphoneChatMessage [%p] destroyed.",msg);
|
||||
}
|
||||
|
||||
|
|
@ -1357,21 +1569,50 @@ LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the path to the file to read from or write to during the file transfer.
|
||||
* @param[in] msg LinphoneChatMessage object
|
||||
* @param[in] filepath The path to the file to use for the file transfer.
|
||||
*/
|
||||
void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath) {
|
||||
if (msg->file_transfer_filepath != NULL) {
|
||||
ms_free(msg->file_transfer_filepath);
|
||||
}
|
||||
msg->file_transfer_filepath = ms_strdup(filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the file to read from or write to during the file transfer.
|
||||
* @param[in] msg LinphoneChatMessage object
|
||||
* @return The path to the file to use for the file transfer.
|
||||
*/
|
||||
const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg) {
|
||||
return msg->file_transfer_filepath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
|
||||
* @param[in] msg LinphoneChatMessage object
|
||||
* @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage.
|
||||
*/
|
||||
LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg) {
|
||||
return msg->callbacks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a message attached to a dedicated chat room with a particular content. Use #linphone_chat_room_send_message2 to initiate the transfer
|
||||
* @param cr the chat room.
|
||||
* @param a #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContent.data is NULL.
|
||||
* @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContent.data is NULL.
|
||||
* @return a new #LinphoneChatMessage
|
||||
*/
|
||||
|
||||
LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content) {
|
||||
LinphoneChatMessage* msg = belle_sip_object_new(LinphoneChatMessage);
|
||||
msg->callbacks=linphone_chat_message_cbs_new();
|
||||
msg->chat_room=(LinphoneChatRoom*)cr;
|
||||
msg->message = NULL;
|
||||
msg->file_transfer_information = (LinphoneContent *)malloc(sizeof(LinphoneContent));
|
||||
memset(msg->file_transfer_information, 0, sizeof(LinphoneContent));
|
||||
linphone_content_copy(msg->file_transfer_information, initial_content);
|
||||
msg->file_transfer_information = linphone_content_copy(initial_content);
|
||||
msg->dir=LinphoneChatMessageOutgoing;
|
||||
linphone_chat_message_set_to(msg, linphone_chat_room_get_peer_address(cr));
|
||||
linphone_chat_message_set_from(msg, linphone_address_new(linphone_core_get_identity(cr->lc)));
|
||||
|
|
|
|||
215
coreapi/content.c
Normal file
215
coreapi/content.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
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 "linphonecore.h"
|
||||
#include "private.h"
|
||||
|
||||
|
||||
|
||||
static void linphone_content_destroy(LinphoneContent *content) {
|
||||
if (content->owned_fields == TRUE) {
|
||||
if (content->lcp.type) belle_sip_free(content->lcp.type);
|
||||
if (content->lcp.subtype) belle_sip_free(content->lcp.subtype);
|
||||
if (content->lcp.data) belle_sip_free(content->lcp.data);
|
||||
if (content->lcp.encoding) belle_sip_free(content->lcp.encoding);
|
||||
if (content->lcp.name) belle_sip_free(content->lcp.name);
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent *ref) {
|
||||
linphone_content_set_type(obj, linphone_content_get_type(ref));
|
||||
linphone_content_set_subtype(obj, linphone_content_get_subtype(ref));
|
||||
linphone_content_set_encoding(obj, linphone_content_get_encoding(ref));
|
||||
linphone_content_set_name(obj, linphone_content_get_name(ref));
|
||||
if (linphone_content_get_buffer(ref) != NULL) {
|
||||
linphone_content_set_buffer(obj, linphone_content_get_buffer(ref), linphone_content_get_size(ref));
|
||||
} else {
|
||||
linphone_content_set_size(obj, linphone_content_get_size(ref));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContent);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneContent, belle_sip_object_t,
|
||||
(belle_sip_object_destroy_t)linphone_content_destroy,
|
||||
(belle_sip_object_clone_t)linphone_content_clone,
|
||||
NULL, // marshal
|
||||
TRUE
|
||||
);
|
||||
|
||||
|
||||
LinphoneContent * linphone_core_create_content(LinphoneCore *lc) {
|
||||
return linphone_content_new();
|
||||
}
|
||||
|
||||
LinphoneContent * linphone_content_ref(LinphoneContent *content) {
|
||||
belle_sip_object_ref(content);
|
||||
return content;
|
||||
}
|
||||
|
||||
void linphone_content_unref(LinphoneContent *content) {
|
||||
belle_sip_object_unref(content);
|
||||
}
|
||||
|
||||
void *linphone_content_get_user_data(const LinphoneContent *content) {
|
||||
return content->user_data;
|
||||
}
|
||||
|
||||
void linphone_content_set_user_data(LinphoneContent *content, void *ud) {
|
||||
content->user_data = ud;
|
||||
}
|
||||
|
||||
const char * linphone_content_get_type(const LinphoneContent *content) {
|
||||
return content->lcp.type;
|
||||
}
|
||||
|
||||
void linphone_content_set_type(LinphoneContent *content, const char *type) {
|
||||
if (content->lcp.type != NULL) {
|
||||
belle_sip_free(content->lcp.type);
|
||||
content->lcp.type = NULL;
|
||||
}
|
||||
if (type != NULL) {
|
||||
content->lcp.type = belle_sip_strdup(type);
|
||||
}
|
||||
}
|
||||
|
||||
const char * linphone_content_get_subtype(const LinphoneContent *content) {
|
||||
return content->lcp.subtype;
|
||||
}
|
||||
|
||||
void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) {
|
||||
if (content->lcp.subtype != NULL) {
|
||||
belle_sip_free(content->lcp.subtype);
|
||||
content->lcp.subtype = NULL;
|
||||
}
|
||||
if (subtype != NULL) {
|
||||
content->lcp.subtype = belle_sip_strdup(subtype);
|
||||
}
|
||||
}
|
||||
|
||||
void * linphone_content_get_buffer(const LinphoneContent *content) {
|
||||
return content->lcp.data;
|
||||
}
|
||||
|
||||
void linphone_content_set_buffer(LinphoneContent *content, const void *buffer, size_t size) {
|
||||
content->lcp.size = size;
|
||||
content->lcp.data = belle_sip_malloc(size + 1);
|
||||
memcpy(content->lcp.data, buffer, size);
|
||||
((char *)content->lcp.data)[size] = '\0';
|
||||
}
|
||||
|
||||
char * linphone_content_get_string_buffer(const LinphoneContent *content) {
|
||||
return (char *)content->lcp.data;
|
||||
}
|
||||
|
||||
void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) {
|
||||
content->lcp.size = strlen(buffer);
|
||||
content->lcp.data = belle_sip_strdup(buffer);
|
||||
}
|
||||
|
||||
size_t linphone_content_get_size(const LinphoneContent *content) {
|
||||
return content->lcp.size;
|
||||
}
|
||||
|
||||
void linphone_content_set_size(LinphoneContent *content, size_t size) {
|
||||
content->lcp.size = size;
|
||||
}
|
||||
|
||||
const char * linphone_content_get_encoding(const LinphoneContent *content) {
|
||||
return content->lcp.encoding;
|
||||
}
|
||||
|
||||
void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) {
|
||||
if (content->lcp.encoding != NULL) {
|
||||
belle_sip_free(content->lcp.encoding);
|
||||
content->lcp.encoding = NULL;
|
||||
}
|
||||
if (encoding != NULL) {
|
||||
content->lcp.encoding = belle_sip_strdup(encoding);
|
||||
}
|
||||
}
|
||||
|
||||
const char * linphone_content_get_name(const LinphoneContent *content) {
|
||||
return content->lcp.name;
|
||||
}
|
||||
|
||||
void linphone_content_set_name(LinphoneContent *content, const char *name) {
|
||||
if (content->lcp.name != NULL) {
|
||||
belle_sip_free(content->lcp.name);
|
||||
content->lcp.name = NULL;
|
||||
}
|
||||
if (name != NULL) {
|
||||
content->lcp.name = belle_sip_strdup(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
LinphoneContent * linphone_content_new(void) {
|
||||
LinphoneContent *content = belle_sip_object_new(LinphoneContent);
|
||||
belle_sip_object_ref(content);
|
||||
content->owned_fields = TRUE;
|
||||
return content;
|
||||
}
|
||||
|
||||
LinphoneContent * linphone_content_copy(const LinphoneContent *ref) {
|
||||
return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref)));
|
||||
}
|
||||
|
||||
LinphoneContent * linphone_content_from_sal_body(const SalBody *ref) {
|
||||
if (ref && ref->type) {
|
||||
LinphoneContent *content = linphone_content_new();
|
||||
linphone_content_set_type(content, ref->type);
|
||||
linphone_content_set_subtype(content, ref->subtype);
|
||||
linphone_content_set_encoding(content, ref->encoding);
|
||||
if (ref->data != NULL) {
|
||||
linphone_content_set_buffer(content, ref->data, ref->size);
|
||||
} else {
|
||||
linphone_content_set_size(content, ref->size);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SalBody *sal_body_from_content(SalBody *body, const LinphoneContent *content) {
|
||||
if (content && linphone_content_get_type(content)) {
|
||||
body->type = linphone_content_get_type(content);
|
||||
body->subtype = linphone_content_get_subtype(content);
|
||||
body->data = linphone_content_get_buffer(content);
|
||||
body->size = linphone_content_get_size(content);
|
||||
body->encoding = linphone_content_get_encoding(content);
|
||||
return body;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LinphoneContent * linphone_content_private_to_linphone_content(const LinphoneContentPrivate *lcp) {
|
||||
LinphoneContent *content = belle_sip_object_new(LinphoneContent);
|
||||
memcpy(&content->lcp, lcp, sizeof(LinphoneContentPrivate));
|
||||
content->owned_fields = FALSE;
|
||||
return content;
|
||||
}
|
||||
|
||||
LinphoneContentPrivate * linphone_content_to_linphone_content_private(const LinphoneContent *content) {
|
||||
return (LinphoneContentPrivate *)&content->lcp;
|
||||
}
|
||||
228
coreapi/content.h
Normal file
228
coreapi/content.h
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
content.h
|
||||
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_CONTENT_H_
|
||||
#define LINPHONE_CONTENT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The LinphoneContent object holds data that can be embedded in a signaling message.
|
||||
**/
|
||||
struct _LinphoneContent;
|
||||
/**
|
||||
* The LinphoneContent object holds data that can be embedded in a signaling message.
|
||||
**/
|
||||
typedef struct _LinphoneContent LinphoneContent;
|
||||
|
||||
/**
|
||||
* @deprecated Use LinphoneContent objects instead of this structure.
|
||||
*/
|
||||
struct _LinphoneContentPrivate{
|
||||
char *type; /**<mime type for the data, for example "application"*/
|
||||
char *subtype; /**<mime subtype for the data, for example "html"*/
|
||||
void *data; /**<the actual data buffer, usually a string. Null when provided by callbacks #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb*/
|
||||
size_t size; /**<the size of the data buffer, excluding null character despite null character is always set for convenience.
|
||||
When provided by callback #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb, it states the total number of bytes of the transfered file*/
|
||||
char *encoding; /**<The encoding of the data buffer, for example "gzip"*/
|
||||
char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias to the LinphoneContentPrivate struct.
|
||||
* @deprecated
|
||||
**/
|
||||
typedef struct _LinphoneContentPrivate LinphoneContentPrivate;
|
||||
|
||||
/**
|
||||
* Convert a LinphoneContentPrivate structure to a LinphoneContent object.
|
||||
* @deprecated Utility macro to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
|
||||
*/
|
||||
#define LINPHONE_CONTENT(lcp) linphone_content_private_to_linphone_content(lcp)
|
||||
|
||||
/**
|
||||
* Convert a LinphoneContentPrivate structure to a LinphoneContent object.
|
||||
* @deprecated Utility function to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneContent * linphone_content_private_to_linphone_content(const LinphoneContentPrivate *lcp);
|
||||
|
||||
/**
|
||||
* Convert a LinphoneContent object to a LinphoneContentPrivate structure.
|
||||
* @deprecated Utility macro to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
|
||||
*/
|
||||
#define LINPHONE_CONTENT_PRIVATE(lc) linphone_content_to_linphone_content_private(lc)
|
||||
|
||||
/**
|
||||
* Convert a LinphoneContent object to a LinphoneContentPrivate structure.
|
||||
* @deprecated Utility function to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneContentPrivate * linphone_content_to_linphone_content_private(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Create a content with default values from Linphone core.
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @return LinphoneContent object with default values set
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneContent * linphone_core_create_content(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Acquire a reference to the content.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The same LinphoneContent object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneContent * linphone_content_ref(LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Release reference to the content.
|
||||
* @param[in] content LinphoneContent object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_content_unref(LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Retrieve the user pointer associated with the content.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The user pointer associated with the content.
|
||||
**/
|
||||
LINPHONE_PUBLIC void *linphone_content_get_user_data(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Assign a user pointer to the content.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] ud The user pointer to associate with the content.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_content_set_user_data(LinphoneContent *content, void *ud);
|
||||
|
||||
/**
|
||||
* Get the mime type of the content data.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The mime type of the content data, for example "application".
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_content_get_type(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the mime type of the content data.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] type The mime type of the content data, for example "application".
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_type(LinphoneContent *content, const char *type);
|
||||
|
||||
/**
|
||||
* Get the mime subtype of the content data.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The mime subtype of the content data, for example "html".
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_content_get_subtype(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the mime subtype of the content data.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] subtype The mime subtype of the content data, for example "html".
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_subtype(LinphoneContent *content, const char *subtype);
|
||||
|
||||
/**
|
||||
* Get the content data buffer, usually a string.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The content data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void * linphone_content_get_buffer(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the content data buffer, usually a string.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] buffer The content data buffer.
|
||||
* @param[in] size The size of the content data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_buffer(LinphoneContent *content, const void *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Get the string content data buffer.
|
||||
* @param[in] content LinphoneContent object
|
||||
* @return The string content data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC char * linphone_content_get_string_buffer(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the string content data buffer.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] buffer The string content data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer);
|
||||
|
||||
/**
|
||||
* Get the content data buffer size, excluding null character despite null character is always set for convenience.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The content data buffer size.
|
||||
*/
|
||||
LINPHONE_PUBLIC size_t linphone_content_get_size(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the content data size, excluding null character despite null character is always set for convenience.
|
||||
* @param[in] content LinphoneContent object
|
||||
* @param[in] size The content data buffer size.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_size(LinphoneContent *content, size_t size);
|
||||
|
||||
/**
|
||||
* Get the encoding of the data buffer, for example "gzip".
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The encoding of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_content_get_encoding(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the encoding of the data buffer, for example "gzip".
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] encoding The encoding of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_encoding(LinphoneContent *content, const char *encoding);
|
||||
|
||||
/**
|
||||
* Get the name associated with a RCS file transfer message. It is used to store the original filename of the file to be downloaded from server.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The name of the content.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_content_get_name(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Set the name associated with a RCS file transfer message. It is used to store the original filename of the file to be downloaded from server.
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] name The name of the content.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_content_set_name(LinphoneContent *content, const char *name);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LINPHONE_CONTENT_H_ */
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 - 2010 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
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"
|
||||
#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, void *window_id) {
|
||||
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, window_id);
|
||||
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);
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
|
|||
case LinphoneStatusVacation:
|
||||
str=_("Vacation");
|
||||
default:
|
||||
str=_("Unknown-bug");
|
||||
str=_("Unknown status");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
############################################################################
|
||||
# CMakeLists.txt
|
||||
# gitversion.cmake
|
||||
# Copyright (C) 2014 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
|
|
|
|||
|
|
@ -48,14 +48,14 @@ static void stop(int signum){
|
|||
/**
|
||||
* function invoked to report file transfer progress.
|
||||
* */
|
||||
static void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress) {
|
||||
static void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) {
|
||||
const LinphoneAddress* from_address = linphone_chat_message_get_from(message);
|
||||
const LinphoneAddress* to_address = linphone_chat_message_get_to(message);
|
||||
char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address);
|
||||
printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)progress
|
||||
printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)((offset *100)/total)
|
||||
,(linphone_chat_message_is_outgoing(message)?"sent":"received")
|
||||
, content->type
|
||||
, content->subtype
|
||||
, linphone_content_get_type(content)
|
||||
, linphone_content_get_subtype(content)
|
||||
,(linphone_chat_message_is_outgoing(message)?"to":"from")
|
||||
, address);
|
||||
free(address);
|
||||
|
|
@ -63,7 +63,7 @@ static void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMess
|
|||
/**
|
||||
* function invoked when a file transfer is received.
|
||||
**/
|
||||
static void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size){
|
||||
static void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size){
|
||||
FILE* file=NULL;
|
||||
if (!linphone_chat_message_get_user_data(message)) {
|
||||
/*first chunk, creating file*/
|
||||
|
|
@ -92,7 +92,7 @@ char big_file [128000];
|
|||
/*
|
||||
* function called when the file transfer is initiated. file content should be feed into object LinphoneContent
|
||||
* */
|
||||
static void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size){
|
||||
static void file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size){
|
||||
int offset=-1;
|
||||
|
||||
if (!linphone_chat_message_get_user_data(message)) {
|
||||
|
|
@ -131,9 +131,9 @@ static void linphone_file_transfer_state_changed(LinphoneChatMessage* msg,Linpho
|
|||
*/
|
||||
static void message_received(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
const LinphoneContent *file_transfer_info = linphone_chat_message_get_file_transfer_information(msg);
|
||||
printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, (long int)file_transfer_info->size);
|
||||
printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", linphone_content_get_name(file_transfer_info), (long int)linphone_content_get_size(file_transfer_info));
|
||||
|
||||
linphone_chat_message_start_file_download(msg, linphone_file_transfer_state_changed);
|
||||
linphone_chat_message_start_file_download(msg, linphone_file_transfer_state_changed, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -145,8 +145,9 @@ int main(int argc, char *argv[]){
|
|||
int i;
|
||||
const char* big_file_content="big file";
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneContent content;
|
||||
LinphoneContent* content;
|
||||
LinphoneChatMessage* chat_message;
|
||||
LinphoneChatMessageCbs *cbs;
|
||||
|
||||
/*seting dummy file content to something*/
|
||||
for (i=0;i<sizeof(big_file);i+=strlen(big_file_content))
|
||||
|
|
@ -160,15 +161,6 @@ 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
|
||||
and file_transfer_progress_indication to print progress.
|
||||
*/
|
||||
vtable.file_transfer_recv=file_transfer_received;
|
||||
vtable.file_transfer_send=file_transfer_send;
|
||||
vtable.file_transfer_progress_indication=file_transfer_progress_indication;
|
||||
vtable.message_received=message_received;
|
||||
|
||||
|
||||
|
|
@ -189,20 +181,30 @@ int main(int argc, char *argv[]){
|
|||
/*Next step is to create a chat room*/
|
||||
chat_room = linphone_core_create_chat_room(lc,dest_friend);
|
||||
|
||||
memset(&content,0,sizeof(content));
|
||||
content.type="text";
|
||||
content.subtype="plain";
|
||||
content.size=sizeof(big_file); /*total size to be transfered*/
|
||||
content.name = "bigfile.txt";
|
||||
content = linphone_core_create_content(lc);
|
||||
linphone_content_set_type(content,"text");
|
||||
linphone_content_set_subtype(content,"plain");
|
||||
linphone_content_set_size(content,sizeof(big_file)); /*total size to be transfered*/
|
||||
linphone_content_set_name(content,"bigfile.txt");
|
||||
|
||||
/*now create a chat message with custom content*/
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the application callbacks. The file_transfer_received callback is used in order to get notifications
|
||||
* about incoming file reception, file_transfer_send to feed file to be transfered and
|
||||
* file_transfer_progress_indication to print progress.
|
||||
*/
|
||||
cbs = linphone_chat_message_get_callbacks(chat_message);
|
||||
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
|
||||
linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send);
|
||||
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
|
||||
|
||||
/*initiating file transfer*/
|
||||
linphone_chat_room_send_message2(chat_room, chat_message, linphone_file_transfer_state_changed, NULL);
|
||||
linphone_chat_room_send_chat_message(chat_room, chat_message);
|
||||
|
||||
/* main loop for receiving incoming messages and doing background linphone core work: */
|
||||
while(running){
|
||||
|
|
@ -212,6 +214,7 @@ int main(int argc, char *argv[]){
|
|||
|
||||
|
||||
printf("Shutting down...\n");
|
||||
linphone_content_unref(content);
|
||||
linphone_chat_room_destroy(chat_room);
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.linphone.core.LinphoneCore.RegistrationState;
|
|||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneCoreListener.LinphoneListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneFriend.SubscribePolicy;
|
||||
|
|
@ -60,7 +60,7 @@ import org.linphone.core.SubscriptionState;
|
|||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialBuddyStatus implements LinphoneCoreListener {
|
||||
public class TutorialBuddyStatus implements LinphoneListener {
|
||||
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.linphone.core.LinphoneCore.RegistrationState;
|
|||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneCoreListener.LinphoneListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
|
|
@ -58,7 +58,7 @@ import org.linphone.core.SubscriptionState;
|
|||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessage.StateListener {
|
||||
public class TutorialChatRoom implements LinphoneListener, LinphoneChatMessage.StateListener {
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,23 +22,23 @@ 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;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneCoreListener.LinphoneListener;
|
||||
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;
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ import org.linphone.core.SubscriptionState;
|
|||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialHelloWorld implements LinphoneCoreListener {
|
||||
public class TutorialHelloWorld implements LinphoneListener {
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.linphone.core.LinphoneCore.RegistrationState;
|
|||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneCoreListener.LinphoneListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
|
|
@ -57,7 +57,7 @@ import org.linphone.core.SubscriptionState;
|
|||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialRegistration implements LinphoneCoreListener {
|
||||
public class TutorialRegistration implements LinphoneListener {
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
|
|
|||
|
|
@ -152,12 +152,12 @@ int main(int argc, char *argv[]){
|
|||
ms_usleep(50000);
|
||||
++i;
|
||||
if (data->ev && i%100==0){
|
||||
LinphoneContent content;
|
||||
LinphoneContentPrivate content;
|
||||
content.type="application";
|
||||
content.subtype="goodxml";
|
||||
content.data="really cool";
|
||||
content.size=strlen((const char*)content.data);
|
||||
linphone_event_notify(data->ev,&content);
|
||||
linphone_event_notify(data->ev,LINPHONE_CONTENT(&content));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,98 +29,23 @@
|
|||
|
||||
|
||||
struct _LinphoneInfoMessage{
|
||||
LinphoneContent content;
|
||||
LinphoneContent *content;
|
||||
SalCustomHeader *headers;
|
||||
};
|
||||
|
||||
#define SET_STRING(ptr,field,val) \
|
||||
if (ptr->field) { \
|
||||
ms_free(ptr->field); \
|
||||
ptr->field=NULL; \
|
||||
} \
|
||||
if (val){ \
|
||||
ptr->field=ms_strdup(val); \
|
||||
}
|
||||
|
||||
void linphone_content_copy(LinphoneContent *obj, const LinphoneContent *ref){
|
||||
SET_STRING(obj,type,ref->type);
|
||||
SET_STRING(obj,subtype,ref->subtype);
|
||||
SET_STRING(obj,encoding,ref->encoding);
|
||||
SET_STRING(obj,name,ref->name);
|
||||
if (obj->data) {
|
||||
ms_free(obj->data);
|
||||
obj->data=NULL;
|
||||
}
|
||||
if (ref->data){
|
||||
obj->data=ms_malloc(ref->size+1);
|
||||
memcpy(obj->data, ref->data, ref->size);
|
||||
((char*)obj->data)[ref->size]='\0';
|
||||
}
|
||||
obj->size=ref->size;
|
||||
}
|
||||
|
||||
void linphone_content_uninit(LinphoneContent * obj){
|
||||
if (obj->type) ms_free(obj->type);
|
||||
if (obj->subtype) ms_free(obj->subtype);
|
||||
if (obj->data) ms_free(obj->data);
|
||||
if (obj->encoding) ms_free(obj->encoding);
|
||||
if (obj->name) ms_free(obj->name);
|
||||
}
|
||||
|
||||
LinphoneContent *linphone_content_copy_from_sal_body(LinphoneContent *obj, const SalBody *ref){
|
||||
SET_STRING(obj,type,ref->type);
|
||||
SET_STRING(obj,subtype,ref->subtype);
|
||||
SET_STRING(obj,encoding,ref->encoding);
|
||||
if (obj->data) {
|
||||
ms_free(obj->data);
|
||||
obj->data=NULL;
|
||||
}
|
||||
if (ref->data){
|
||||
obj->data=ms_malloc(ref->size+1);
|
||||
memcpy(obj->data, ref->data, ref->size);
|
||||
((char*)obj->data)[ref->size]='\0';
|
||||
}
|
||||
obj->size=ref->size;
|
||||
return obj;
|
||||
}
|
||||
|
||||
const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref){
|
||||
if (ref && ref->type){
|
||||
obj->type=(char*)ref->type;
|
||||
obj->subtype=(char*)ref->subtype;
|
||||
obj->data=(void*)ref->data;
|
||||
obj->encoding=(char*)ref->encoding;
|
||||
obj->size=ref->size;
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SalBody *sal_body_from_content(SalBody *body, const LinphoneContent *lc){
|
||||
if (lc && lc->type){
|
||||
body->type=lc->type;
|
||||
body->subtype=lc->subtype;
|
||||
body->data=lc->data;
|
||||
body->size=lc->size;
|
||||
body->encoding=lc->encoding;
|
||||
return body;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a LinphoneInfoMessage
|
||||
**/
|
||||
void linphone_info_message_destroy(LinphoneInfoMessage *im){
|
||||
linphone_content_uninit(&im->content);
|
||||
sal_custom_header_free(im->headers);
|
||||
if (im->content) linphone_content_unref(im->content);
|
||||
if (im->headers) sal_custom_header_free(im->headers);
|
||||
ms_free(im);
|
||||
}
|
||||
|
||||
|
||||
LinphoneInfoMessage *linphone_info_message_copy(const LinphoneInfoMessage *orig){
|
||||
LinphoneInfoMessage *im=ms_new0(LinphoneInfoMessage,1);
|
||||
linphone_content_copy(&im->content,&orig->content);
|
||||
if (orig->content) im->content=linphone_content_copy(orig->content);
|
||||
if (orig->headers) im->headers=sal_custom_header_clone(orig->headers);
|
||||
return im;
|
||||
}
|
||||
|
|
@ -146,7 +71,7 @@ LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore *lc){
|
|||
int linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info){
|
||||
SalBody body;
|
||||
sal_op_set_sent_custom_header(call->op,info->headers);
|
||||
return sal_send_info(call->op,NULL, NULL, sal_body_from_content(&body,&info->content));
|
||||
return sal_send_info(call->op,NULL, NULL, sal_body_from_content(&body,info->content));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -176,14 +101,14 @@ const char *linphone_info_message_get_header(const LinphoneInfoMessage *im, cons
|
|||
* All fields of the LinphoneContent are copied, thus the application can destroy/modify/recycloe the content object freely ater the function returns.
|
||||
**/
|
||||
void linphone_info_message_set_content(LinphoneInfoMessage *im, const LinphoneContent *content){
|
||||
linphone_content_copy(&im->content,content);
|
||||
im->content=linphone_content_copy(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the info message's content as a #LinphoneContent structure.
|
||||
**/
|
||||
const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im){
|
||||
return im->content.type ? &im->content : NULL;
|
||||
return (im->content && linphone_content_get_type(im->content)) ? im->content : NULL;
|
||||
}
|
||||
|
||||
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody *body){
|
||||
|
|
@ -191,7 +116,7 @@ void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody
|
|||
if (call){
|
||||
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 (body) info->content=linphone_content_from_sal_body(body);
|
||||
linphone_core_notify_info_received(lc,call,info);
|
||||
linphone_info_message_destroy(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,6 +246,10 @@ bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel){
|
|||
return bcTunnel(tunnel)->isConnected();
|
||||
}
|
||||
|
||||
bool_t linphone_tunnel_get_activated(const LinphoneTunnel *tunnel){
|
||||
return bcTunnel(tunnel)->isActivated();
|
||||
}
|
||||
|
||||
static OrtpLogFunc tunnelOrtpLogHandler=NULL;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ typedef enum _LinphoneTunnelMode {
|
|||
} LinphoneTunnelMode;
|
||||
|
||||
/**
|
||||
* @brief Convert a string into LinphoneTunnelMode enum
|
||||
* 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.
|
||||
|
|
@ -68,7 +68,7 @@ typedef enum _LinphoneTunnelMode {
|
|||
LINPHONE_PUBLIC LinphoneTunnelMode string_to_tunnel_mode(const char *string);
|
||||
|
||||
/**
|
||||
* @brief Convert a tunnel mode enum into string
|
||||
* Convert a tunnel mode enum into string
|
||||
* @param mode Enum to convert
|
||||
* @return "disable", "enable" or "auto"
|
||||
*/
|
||||
|
|
@ -80,170 +80,175 @@ LINPHONE_PUBLIC const char *tunnel_mode_to_string(LinphoneTunnelMode mode);
|
|||
LINPHONE_PUBLIC LinphoneTunnelConfig *linphone_tunnel_config_new(void);
|
||||
|
||||
/**
|
||||
* Set address of server.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* @param host tunnel server ip address
|
||||
* Set the IP address or hostname of the tunnel server.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @param host The tunnel server IP address or hostname
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *host);
|
||||
|
||||
/**
|
||||
* Get address of server.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* Get the IP address or hostname of the tunnel server.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @return The tunnel server IP address or hostname
|
||||
*/
|
||||
LINPHONE_PUBLIC const char *linphone_tunnel_config_get_host(const LinphoneTunnelConfig *tunnel);
|
||||
|
||||
/**
|
||||
* Set tls port of server.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* @param port tunnel server tls port, recommended value is 443
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @param port The tunnel server TLS port, recommended value is 443
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port);
|
||||
|
||||
/**
|
||||
* Get tls port of server.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* Get the TLS port of the tunnel server.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @return The TLS port of the tunnel server
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_tunnel_config_get_port(const LinphoneTunnelConfig *tunnel);
|
||||
|
||||
/**
|
||||
* Set the remote port on the tunnel server side used to test udp reachability.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* @param remote_udp_mirror_port remote port on the tunnel server side used to test udp reachability, set to -1 to disable the feature
|
||||
* Set the remote port on the tunnel server side used to test UDP reachability.
|
||||
* This is used when the mode is set auto, to detect whether the tunnel has to be enabled or not.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @param remote_udp_mirror_port The remote port on the tunnel server side used to test UDP reachability, set to -1 to disable the feature
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel, int remote_udp_mirror_port);
|
||||
|
||||
/**
|
||||
* Get the remote port on the tunnel server side used to test udp reachability.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* Get the remote port on the tunnel server side used to test UDP reachability.
|
||||
* This is used when the mode is set auto, to detect whether the tunnel has to be enabled or not.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @return The remote port on the tunnel server side used to test UDP reachability
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_tunnel_config_get_remote_udp_mirror_port(const LinphoneTunnelConfig *tunnel);
|
||||
|
||||
/**
|
||||
* Set the udp packet round trip delay in ms for a tunnel configuration.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* @param delay udp packet round trip delay in ms considered as acceptable. recommended value is 1000 ms.
|
||||
* Set the UDP packet round trip delay in ms for a tunnel configuration.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @param delay The UDP packet round trip delay in ms considered as acceptable (recommended value is 1000 ms).
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay);
|
||||
|
||||
/**
|
||||
* Get the udp packet round trip delay in ms for a tunnel configuration.
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* Get the UDP packet round trip delay in ms for a tunnel configuration.
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
* @return The UDP packet round trip delay in ms.
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel);
|
||||
|
||||
/**
|
||||
* Destroy a tunnel configuration
|
||||
*
|
||||
* @param tunnel configuration object
|
||||
* @param tunnel LinphoneTunnelConfig object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel);
|
||||
|
||||
/**
|
||||
* Add tunnel server configuration
|
||||
*
|
||||
* @param tunnel object
|
||||
* @param tunnel_config object
|
||||
* Add a tunnel server configuration.
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param tunnel_config LinphoneTunnelConfig object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config);
|
||||
|
||||
/**
|
||||
* @brief Remove tunnel server configuration
|
||||
* @param tunnel object
|
||||
* @param tunnel_config object
|
||||
* Remove a tunnel server configuration.
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param tunnel_config LinphoneTunnelConfig object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config);
|
||||
|
||||
/**
|
||||
* @brief Get added servers
|
||||
* @param tunnel A LinphoneTunnel object
|
||||
* @return A list of LinphoneTunnelConfig objects
|
||||
* Get added servers
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @return \mslist{LinphoneTunnelConfig}
|
||||
*/
|
||||
LINPHONE_PUBLIC const MSList *linphone_tunnel_get_servers(const LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @brief Removes all tunnel server address previously entered with addServer()
|
||||
* @param tunnel A LinphoneTunnel object
|
||||
* Remove all tunnel server addresses previously entered with linphone_tunnel_add_server()
|
||||
* @param tunnel LinphoneTunnel object
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @brief Set tunnel mode
|
||||
* Set the 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 mode See #LinphoneTunnelMode
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param mode The desired LinphoneTunnelMode
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTunnelMode mode);
|
||||
|
||||
/**
|
||||
* @brief Get the tunnel mode
|
||||
* @param tunnel A LinphoneTunnel object
|
||||
* @return Return a #LinphoneTunnelMode enumeration
|
||||
* Get the tunnel mode
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @return The current LinphoneTunnelMode
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @brief Check whether the tunnel is connected
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @return True if the tunnel is connected
|
||||
* Returns whether the tunnel is activated. If mode is set to auto, this gives indication whether the automatic detection determined
|
||||
* that tunnel was necessary or not.
|
||||
* @param tunnel the tunnel
|
||||
* @return TRUE if tunnel is in use, FALSE otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_tunnel_get_activated(const LinphoneTunnel *tunnel);
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the tunnel is connected
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @return A boolean value telling if the tunnel is connected
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @param tunnel object
|
||||
* Forces reconnection to the tunnel server.
|
||||
* Force 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
|
||||
* won't be notified promptly that its connection is now zombie, so it is recommended to call this method that will cause
|
||||
* the lost connection to be closed and new connection to be issued.
|
||||
* @param tunnel LinphoneTunnel object
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_reconnect(LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @brief Set whether SIP packets must be directly sent to a UA or pass through the tunnel
|
||||
* @param tunnel Tunnel to configure
|
||||
* Set whether SIP packets must be directly sent to a UA or pass through the tunnel
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param enable If true, SIP packets shall pass through the tunnel
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_enable_sip(LinphoneTunnel *tunnel, bool_t enable);
|
||||
|
||||
/**
|
||||
* @brief Check whether tunnel is set to transport SIP packets
|
||||
* @param tunnel Tunnel to check
|
||||
* @return True, SIP packets shall pass through through tunnel
|
||||
* Check whether tunnel is set to transport SIP packets
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @return A boolean value telling whether SIP packets shall pass through the 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.
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param host Http proxy host.
|
||||
* @param port http proxy port.
|
||||
* @param username optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
|
||||
* @param passwd optional http proxy password. Use NULL if not needed.
|
||||
* @param host http proxy host
|
||||
* @param port http proxy port
|
||||
* @param username Optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
|
||||
* @param passwd Optional http proxy password. Use NULL if not needed.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_set_http_proxy(LinphoneTunnel *tunnel, const char *host, int port, const char* username,const char* passwd);
|
||||
|
||||
/**
|
||||
* Retrieve optional http proxy configuration previously set with linphone_tunnel_set_http_proxy().
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param host Http proxy host.
|
||||
* @param port http proxy port.
|
||||
* @param username optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
|
||||
* @param passwd optional http proxy password. Use NULL if not needed.
|
||||
* @param host http proxy host
|
||||
* @param port http proxy port
|
||||
* @param username Optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed.
|
||||
* @param passwd Optional http proxy password. Use NULL if not needed.
|
||||
**/
|
||||
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
|
||||
* Set authentication info for the http proxy
|
||||
* @param tunnel LinphoneTunnel object
|
||||
* @param username User name
|
||||
* @param passwd Password
|
||||
|
|
@ -251,38 +256,37 @@ LINPHONE_PUBLIC void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const
|
|||
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
|
||||
* 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.
|
||||
*
|
||||
* @deprecated Replaced by linphone_tunnel_set_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
|
||||
* Check whether tunnel is enabled
|
||||
* @param tunnel Tunnel object
|
||||
* @return Returns a boolean indicating whether tunneled operation is enabled.
|
||||
* @deprecated Replaced by linphone_tunnel_get_mode()
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_tunnel_enabled(const LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by linphone_tunnel_set_mode(LinphoneTunnelModeAuto)
|
||||
* @brief Start tunnel need detection.
|
||||
* 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.
|
||||
* In auto detect mode, the tunnel manager try to establish a real time rtp communication with the tunnel server on specified port.
|
||||
* <br>In case of success, the tunnel is automatically turned off. Otherwise, if no udp communication is feasible, tunnel mode is turned on.
|
||||
* <br> Call this method each time to run the auto detection algorithm
|
||||
* @deprecated Replaced by linphone_tunnel_set_mode(LinphoneTunnelModeAuto)
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by linphone_tunnel_get_mode()
|
||||
* @brief Tells whether tunnel auto detection is enabled.
|
||||
* Tell whether tunnel auto detection is enabled.
|
||||
* @param[in] tunnel LinphoneTunnel object.
|
||||
* @return TRUE if auto detection is enabled, FALSE otherwise.
|
||||
* @deprecated Replaced by linphone_tunnel_get_mode()
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel){
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool_t linphone_tunnel_get_activated(const LinphoneTunnel *tunnel){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_tunnel_enable_logs_with_handler(LinphoneTunnel *tunnel, bool_t enabled, OrtpLogFunc logHandler){
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ static void linphone_call_audiostream_encryption_changed(void *data, bool_t encr
|
|||
{
|
||||
const LinphoneCallParams *params=linphone_call_get_current_params(call);
|
||||
if (params->has_video) {
|
||||
OrtpZrtpParams params;
|
||||
MSZrtpParams params;
|
||||
ms_message("Trying to enable encryption on video stream");
|
||||
params.zid_file=NULL; //unused
|
||||
video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms);
|
||||
|
|
@ -219,9 +219,9 @@ void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t
|
|||
ms_error("linphone_call_set_authentication_token_verified(): No zrtp context.");
|
||||
}
|
||||
if (!call->auth_token_verified && verified){
|
||||
ortp_zrtp_sas_verified(call->audiostream->ms.sessions.zrtp_context);
|
||||
ms_zrtp_sas_verified(call->audiostream->ms.sessions.zrtp_context);
|
||||
}else if (call->auth_token_verified && !verified){
|
||||
ortp_zrtp_sas_reset_verified(call->audiostream->ms.sessions.zrtp_context);
|
||||
ms_zrtp_sas_reset_verified(call->audiostream->ms.sessions.zrtp_context);
|
||||
}
|
||||
call->auth_token_verified=verified;
|
||||
propagate_encryption_changed(call);
|
||||
|
|
@ -381,6 +381,19 @@ void linphone_call_increment_local_media_description(LinphoneCall *call){
|
|||
md->session_ver++;
|
||||
}
|
||||
|
||||
void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall *call){
|
||||
if (call->ice_session != NULL) {
|
||||
_update_local_media_description_from_ice(call->localdesc, call->ice_session);
|
||||
linphone_core_update_ice_state_in_call_stats(call);
|
||||
}
|
||||
#ifdef BUILD_UPNP
|
||||
if(call->upnp_session != NULL) {
|
||||
linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session);
|
||||
linphone_core_update_upnp_state_in_call_stats(call);
|
||||
}
|
||||
#endif //BUILD_UPNP
|
||||
}
|
||||
|
||||
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
|
|
@ -463,18 +476,9 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
|
|||
setup_rtcp_xr(call, md);
|
||||
|
||||
update_media_description_from_stun(md,&call->ac,&call->vc);
|
||||
if (call->ice_session != NULL) {
|
||||
linphone_core_update_local_media_description_from_ice(md, call->ice_session);
|
||||
linphone_core_update_ice_state_in_call_stats(call);
|
||||
}
|
||||
#ifdef BUILD_UPNP
|
||||
if(call->upnp_session != NULL) {
|
||||
linphone_core_update_local_media_description_from_upnp(md, call->upnp_session);
|
||||
linphone_core_update_upnp_state_in_call_stats(call);
|
||||
}
|
||||
#endif //BUILD_UPNP
|
||||
linphone_address_destroy(addr);
|
||||
call->localdesc=md;
|
||||
linphone_call_update_local_media_description_from_ice_or_upnp(call);
|
||||
linphone_address_destroy(addr);
|
||||
if (old_md){
|
||||
call->localdesc_changed=sal_media_description_equals(md,old_md);
|
||||
sal_media_description_unref(old_md);
|
||||
|
|
@ -564,7 +568,6 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
|
|||
ms_message("New LinphoneCall [%p] initialized (LinphoneCore version: %s)",call,linphone_core_get_version());
|
||||
call->state=LinphoneCallIdle;
|
||||
call->transfer_state = LinphoneCallIdle;
|
||||
call->media_start_time=0;
|
||||
call->log=linphone_call_log_new(call->dir, from, to);
|
||||
call->camera_enabled=TRUE;
|
||||
call->current_params = linphone_call_params_new();
|
||||
|
|
@ -841,7 +844,50 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
return call;
|
||||
}
|
||||
|
||||
/* this function is called internally to get rid of a call.
|
||||
/*
|
||||
* Frees the media resources of the call.
|
||||
* This has to be done at the earliest, unlike signaling resources that sometimes need to be kept a bit more longer.
|
||||
* It is called by linphone_call_set_terminated() (for termination of calls signaled to the application), or directly by the destructor of LinphoneCall
|
||||
* (_linphone_call_destroy) if the call was never notified to the application.
|
||||
*/
|
||||
void linphone_call_free_media_resources(LinphoneCall *call){
|
||||
linphone_call_stop_media_streams(call);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[0]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[1]);
|
||||
linphone_call_delete_upnp_session(call);
|
||||
linphone_call_delete_ice_session(call);
|
||||
linphone_call_stats_uninit(&call->stats[0]);
|
||||
linphone_call_stats_uninit(&call->stats[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called internally when reaching the Released state, to perform cleanups to break circular references.
|
||||
**/
|
||||
static void linphone_call_set_released(LinphoneCall *call){
|
||||
if (call->op!=NULL) {
|
||||
/*transfer the last error so that it can be obtained even in Released state*/
|
||||
if (call->non_op_error.reason==SalReasonNone){
|
||||
const SalErrorInfo *ei=sal_op_get_error_info(call->op);
|
||||
sal_error_info_set(&call->non_op_error,ei->reason,ei->protocol_code,ei->status_string,ei->warnings);
|
||||
}
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
/*it is necessary to reset pointers to other call to prevent circular references that would result in memory never freed.*/
|
||||
if (call->referer){
|
||||
linphone_call_unref(call->referer);
|
||||
call->referer=NULL;
|
||||
}
|
||||
if (call->transfer_target){
|
||||
linphone_call_unref(call->transfer_target);
|
||||
call->transfer_target=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
/* this function is called internally to get rid of a call that was notified to the application, because it reached the end or error state.
|
||||
It performs the following tasks:
|
||||
- remove the call from the internal list of calls
|
||||
- update the call logs accordingly
|
||||
|
|
@ -850,17 +896,9 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
static void linphone_call_set_terminated(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
|
||||
linphone_call_stop_media_streams(call);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[0]);
|
||||
ms_media_stream_sessions_uninit(&call->sessions[1]);
|
||||
linphone_call_delete_upnp_session(call);
|
||||
linphone_call_delete_ice_session(call);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
linphone_call_stats_uninit(&call->stats[0]);
|
||||
linphone_call_stats_uninit(&call->stats[1]);
|
||||
linphone_call_free_media_resources(call);
|
||||
linphone_call_log_completed(call);
|
||||
|
||||
|
||||
if (call == lc->current_call){
|
||||
ms_message("Resetting the current call");
|
||||
lc->current_call=NULL;
|
||||
|
|
@ -869,7 +907,6 @@ static void linphone_call_set_terminated(LinphoneCall *call){
|
|||
if (linphone_core_del_call(lc,call) != 0){
|
||||
ms_error("Could not remove the call from the list !!!");
|
||||
}
|
||||
|
||||
linphone_core_conference_check_uninit(lc);
|
||||
if (call->ringing_beep){
|
||||
linphone_core_stop_dtmf(lc);
|
||||
|
|
@ -924,15 +961,15 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){
|
|||
return "LinphoneCallUpdating";
|
||||
case LinphoneCallReleased:
|
||||
return "LinphoneCallReleased";
|
||||
case LinphoneCallEarlyUpdatedByRemote:
|
||||
return "LinphoneCallEarlyUpdatedByRemote";
|
||||
case LinphoneCallEarlyUpdating:
|
||||
return "LinphoneCallEarlyUpdating";
|
||||
}
|
||||
return "undefined state";
|
||||
}
|
||||
|
||||
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message) {
|
||||
linphone_call_set_state_base(call, cstate, message,FALSE);
|
||||
}
|
||||
|
||||
void linphone_call_set_state_base(LinphoneCall *call, LinphoneCallState cstate, const char *message,bool_t silently){
|
||||
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){
|
||||
LinphoneCore *lc=call->core;
|
||||
|
||||
if (call->state!=cstate){
|
||||
|
|
@ -968,43 +1005,27 @@ void linphone_call_set_state_base(LinphoneCall *call, LinphoneCallState cstate,
|
|||
}
|
||||
if (cstate == LinphoneCallConnected) {
|
||||
call->log->status=LinphoneCallSuccess;
|
||||
call->media_start_time=time(NULL);
|
||||
call->log->connected_date_time=time(NULL);
|
||||
}
|
||||
|
||||
if (!silently)
|
||||
linphone_core_notify_call_state_changed(lc,call,cstate,message);
|
||||
|
||||
linphone_core_notify_call_state_changed(lc,call,cstate,message);
|
||||
linphone_reporting_call_state_updated(call);
|
||||
|
||||
|
||||
/*cancelling DTMF sequence, if any*/
|
||||
if (cstate!=LinphoneCallStreamsRunning && call->dtmfs_timer!=NULL){
|
||||
linphone_call_cancel_dtmfs(call);
|
||||
}
|
||||
if (cstate==LinphoneCallReleased){
|
||||
if (call->op!=NULL) {
|
||||
/*transfer the last error so that it can be obtained even in Released state*/
|
||||
if (call->non_op_error.reason==SalReasonNone){
|
||||
const SalErrorInfo *ei=sal_op_get_error_info(call->op);
|
||||
sal_error_info_set(&call->non_op_error,ei->reason,ei->protocol_code,ei->status_string,ei->warnings);
|
||||
}
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
/*it is necessary to reset pointers to other call to prevent circular references that would result in memory never freed.*/
|
||||
if (call->referer){
|
||||
linphone_call_unref(call->referer);
|
||||
call->referer=NULL;
|
||||
}
|
||||
if (call->transfer_target){
|
||||
linphone_call_unref(call->transfer_target);
|
||||
call->transfer_target=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
linphone_call_set_released(call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_call_destroy(LinphoneCall *obj)
|
||||
{
|
||||
static void linphone_call_destroy(LinphoneCall *obj){
|
||||
ms_message("Call [%p] freed.",obj);
|
||||
if (obj->audiostream || obj->videostream){
|
||||
linphone_call_free_media_resources(obj);
|
||||
}
|
||||
if (obj->op!=NULL) {
|
||||
sal_op_release(obj->op);
|
||||
obj->op=NULL;
|
||||
|
|
@ -1023,9 +1044,11 @@ static void linphone_call_destroy(LinphoneCall *obj)
|
|||
}
|
||||
if (obj->ping_op) {
|
||||
sal_op_release(obj->ping_op);
|
||||
obj->ping_op=NULL;
|
||||
}
|
||||
if (obj->refer_to){
|
||||
ms_free(obj->refer_to);
|
||||
obj->refer_to=NULL;
|
||||
}
|
||||
if (obj->referer){
|
||||
linphone_call_unref(obj->referer);
|
||||
|
|
@ -1033,16 +1056,30 @@ static void linphone_call_destroy(LinphoneCall *obj)
|
|||
}
|
||||
if (obj->transfer_target){
|
||||
linphone_call_unref(obj->transfer_target);
|
||||
obj->transfer_target=NULL;
|
||||
}
|
||||
if (obj->log)
|
||||
if (obj->log) {
|
||||
linphone_call_log_unref(obj->log);
|
||||
obj->log=NULL;
|
||||
}
|
||||
if (obj->auth_token) {
|
||||
ms_free(obj->auth_token);
|
||||
obj->auth_token=NULL;
|
||||
}
|
||||
if (obj->dtmfs_timer) {
|
||||
linphone_call_cancel_dtmfs(obj);
|
||||
}
|
||||
if (obj->params){
|
||||
linphone_call_params_unref(obj->params);
|
||||
obj->params=NULL;
|
||||
}
|
||||
if (obj->current_params){
|
||||
linphone_call_params_unref(obj->current_params);
|
||||
obj->current_params=NULL;
|
||||
}
|
||||
linphone_call_params_unref(obj->params);
|
||||
linphone_call_params_unref(obj->current_params);
|
||||
if (obj->remote_params != NULL) {
|
||||
linphone_call_params_unref(obj->remote_params);
|
||||
obj->remote_params=NULL;
|
||||
}
|
||||
sal_error_info_reset(&obj->non_op_error);
|
||||
}
|
||||
|
|
@ -1280,8 +1317,8 @@ bool_t linphone_call_has_transfer_pending(const LinphoneCall *call){
|
|||
* Returns call's duration in seconds.
|
||||
**/
|
||||
int linphone_call_get_duration(const LinphoneCall *call){
|
||||
if (call->media_start_time==0) return 0;
|
||||
return time(NULL)-call->media_start_time;
|
||||
if (call->log->connected_date_time==0) return 0;
|
||||
return time(NULL)-call->log->connected_date_time;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1485,7 +1522,7 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){
|
|||
if (has_video) _linphone_call_prepare_ice_for_stream(call,1,TRUE);
|
||||
/*start ICE gathering*/
|
||||
if (incoming_offer)
|
||||
linphone_core_update_ice_from_remote_media_description(call,remote); /*this may delete the ice session*/
|
||||
linphone_call_update_ice_from_remote_media_description(call,remote); /*this may delete the ice session*/
|
||||
if (call->ice_session && !ice_session_candidates_gathered(call->ice_session)){
|
||||
if (call->audiostream->ms.state==MSStreamInitialized)
|
||||
audio_stream_prepare_sound(call->audiostream, NULL, NULL);
|
||||
|
|
@ -1876,11 +1913,14 @@ static void configure_rtp_session_for_rtcp_xr(LinphoneCore *lc, LinphoneCall *ca
|
|||
OrtpRtcpXrConfiguration currentconfig;
|
||||
const SalStreamDescription *localstream;
|
||||
const SalStreamDescription *remotestream;
|
||||
SalMediaDescription *remotedesc = sal_call_get_remote_media_description(call->op);
|
||||
|
||||
if (!remotedesc) return;
|
||||
|
||||
localstream = sal_media_description_find_best_stream(call->localdesc, type);
|
||||
if (!localstream) return;
|
||||
localconfig = &localstream->rtcp_xr;
|
||||
remotestream = sal_media_description_find_best_stream(sal_call_get_remote_media_description(call->op), type);
|
||||
remotestream = sal_media_description_find_best_stream(remotedesc, type);
|
||||
if (!remotestream) return;
|
||||
remoteconfig = &remotestream->rtcp_xr;
|
||||
|
||||
|
|
@ -1986,8 +2026,8 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
|
|||
crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag);
|
||||
|
||||
if (crypto_idx >= 0) {
|
||||
media_stream_set_srtp_recv_key(&call->audiostream->ms,stream->crypto[0].algo,stream->crypto[0].master_key);
|
||||
media_stream_set_srtp_send_key(&call->audiostream->ms,stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key);
|
||||
media_stream_set_srtp_recv_key(&call->audiostream->ms,stream->crypto[0].algo,stream->crypto[0].master_key, TRUE);
|
||||
media_stream_set_srtp_send_key(&call->audiostream->ms,stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key, TRUE);
|
||||
} else {
|
||||
ms_warning("Failed to find local crypto algo with tag: %d", stream->crypto_local_tag);
|
||||
}
|
||||
|
|
@ -2108,8 +2148,8 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
if (sal_stream_description_has_srtp(vstream) == TRUE) {
|
||||
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, vstream->crypto_local_tag);
|
||||
if (crypto_idx >= 0) {
|
||||
media_stream_set_srtp_recv_key(&call->videostream->ms,vstream->crypto[0].algo,vstream->crypto[0].master_key);
|
||||
media_stream_set_srtp_send_key(&call->videostream->ms,vstream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key);
|
||||
media_stream_set_srtp_recv_key(&call->videostream->ms,vstream->crypto[0].algo,vstream->crypto[0].master_key, TRUE);
|
||||
media_stream_set_srtp_send_key(&call->videostream->ms,vstream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key, TRUE);
|
||||
}
|
||||
}
|
||||
configure_rtp_session_for_rtcp_xr(lc, call, SalVideo);
|
||||
|
|
@ -2189,15 +2229,15 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
call->up_bw=linphone_core_get_upload_bandwidth(lc);
|
||||
|
||||
if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) {
|
||||
OrtpZrtpParams params;
|
||||
memset(¶ms,0,sizeof(OrtpZrtpParams));
|
||||
MSZrtpParams params;
|
||||
memset(¶ms,0,sizeof(MSZrtpParams));
|
||||
/*call->current_params.media_encryption will be set later when zrtp is activated*/
|
||||
params.zid_file=lc->zrtp_secrets_cache;
|
||||
audio_stream_enable_zrtp(call->audiostream,¶ms);
|
||||
#if VIDEO_ENABLED
|
||||
if (media_stream_secured((MediaStream *)call->audiostream) && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) {
|
||||
/*audio stream is already encrypted and video stream is active*/
|
||||
memset(¶ms,0,sizeof(OrtpZrtpParams));
|
||||
memset(¶ms,0,sizeof(MSZrtpParams));
|
||||
video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2229,9 +2269,9 @@ static bool_t update_stream_crypto_params(LinphoneCall *call, const SalStreamDes
|
|||
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
|
||||
if (crypto_idx >= 0) {
|
||||
if (call->localdesc_changed & SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED)
|
||||
media_stream_set_srtp_send_key(ms,new_stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key);
|
||||
media_stream_set_srtp_send_key(ms,new_stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key, TRUE);
|
||||
if (strcmp(old_stream->crypto[0].master_key,new_stream->crypto[0].master_key)!=0){
|
||||
media_stream_set_srtp_recv_key(ms,new_stream->crypto[0].algo,new_stream->crypto[0].master_key);
|
||||
media_stream_set_srtp_recv_key(ms,new_stream->crypto[0].algo,new_stream->crypto[0].master_key,TRUE);
|
||||
}
|
||||
return TRUE;
|
||||
} else {
|
||||
|
|
@ -2526,6 +2566,27 @@ const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) {
|
|||
return stats;
|
||||
}
|
||||
|
||||
static bool_t ice_in_progress(LinphoneCallStats *stats){
|
||||
return stats->ice_state==LinphoneIceStateInProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether an operation is in progress at the media side.
|
||||
* It can a bad idea to initiate signaling operations (adding video, pausing the call, removing video, changing video parameters) while
|
||||
* the media is busy in establishing the connection (typically ICE connectivity checks). It can result in failures generating loss of time
|
||||
* in future operations in the call.
|
||||
* Applications are invited to check this function after each call state change to decide whether certain operations are permitted or not.
|
||||
* @param call the call
|
||||
* @return TRUE if media is busy in establishing the connection, FALSE otherwise.
|
||||
**/
|
||||
bool_t linphone_call_media_in_progress(LinphoneCall *call){
|
||||
bool_t ret=FALSE;
|
||||
if (ice_in_progress(&call->stats[LINPHONE_CALL_STATS_AUDIO]) || ice_in_progress(&call->stats[LINPHONE_CALL_STATS_VIDEO]))
|
||||
ret=TRUE;
|
||||
/*TODO: could check zrtp state, upnp state*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local loss rate since last report
|
||||
* @return The sender loss rate
|
||||
|
|
@ -2803,6 +2864,8 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
|
|||
break;
|
||||
case LinphoneCallIdle:
|
||||
linphone_call_stop_media_streams_for_ice_gathering(call);
|
||||
linphone_call_update_local_media_description_from_ice_or_upnp(call);
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
linphone_core_notify_incoming_call(call->core, call);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2939,7 +3002,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
|
||||
linphone_call_handle_stream_events(call,0);
|
||||
linphone_call_handle_stream_events(call,1);
|
||||
if (call->state==LinphoneCallStreamsRunning && one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 )
|
||||
if (call->state==LinphoneCallStreamsRunning && one_second_elapsed && call->audiostream!=NULL
|
||||
&& call->audiostream->ms.state==MSStreamStarted && disconnect_timeout>0 )
|
||||
disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout);
|
||||
if (disconnected)
|
||||
linphone_core_disconnected(call->core,call);
|
||||
|
|
@ -2948,7 +3012,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
void linphone_call_log_completed(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
|
||||
call->log->duration=time(NULL)-call->log->start_date_time;
|
||||
call->log->duration=linphone_call_get_duration(call); /*store duration since connected*/
|
||||
|
||||
if (call->log->status==LinphoneCallMissed){
|
||||
char *info;
|
||||
|
|
@ -3097,3 +3161,76 @@ void linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *
|
|||
if (call->params) linphone_call_params_unref(call->params);
|
||||
call->params=cp;
|
||||
}
|
||||
|
||||
static int send_dtmf_handler(void *data, unsigned int revents){
|
||||
LinphoneCall *call = (LinphoneCall*)data;
|
||||
/*By default we send DTMF RFC2833 if we do not have enabled SIP_INFO but we can also send RFC2833 and SIP_INFO*/
|
||||
if (linphone_core_get_use_rfc2833_for_dtmf(call->core)!=0 || linphone_core_get_use_info_for_dtmf(call->core)==0)
|
||||
{
|
||||
/* In Band DTMF */
|
||||
if (call->audiostream!=NULL){
|
||||
audio_stream_send_dtmf(call->audiostream,*call->dtmf_sequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_error("Cannot send RFC2833 DTMF when we are not in communication.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (linphone_core_get_use_info_for_dtmf(call->core)!=0){
|
||||
/* Out of Band DTMF (use INFO method) */
|
||||
sal_call_send_dtmf(call->op,*call->dtmf_sequence);
|
||||
}
|
||||
|
||||
/*this check is needed because linphone_call_send_dtmf does not set the timer since its a single character*/
|
||||
if (call->dtmfs_timer!=NULL) {
|
||||
memmove(call->dtmf_sequence, call->dtmf_sequence+1, strlen(call->dtmf_sequence));
|
||||
}
|
||||
/* continue only if the dtmf sequence is not empty*/
|
||||
if (call->dtmf_sequence!=NULL&&*call->dtmf_sequence!='\0') {
|
||||
return TRUE;
|
||||
} else {
|
||||
linphone_call_cancel_dtmfs(call);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
int linphone_call_send_dtmf(LinphoneCall *call,char dtmf){
|
||||
if (call==NULL){
|
||||
ms_warning("linphone_call_send_dtmf(): invalid call, canceling DTMF.");
|
||||
return -1;
|
||||
}
|
||||
call->dtmf_sequence = &dtmf;
|
||||
send_dtmf_handler(call,0);
|
||||
call->dtmf_sequence = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_call_send_dtmfs(LinphoneCall *call,char *dtmfs) {
|
||||
if (call==NULL){
|
||||
ms_warning("linphone_call_send_dtmfs(): invalid call, canceling DTMF sequence.");
|
||||
return -1;
|
||||
}
|
||||
if (call->dtmfs_timer!=NULL){
|
||||
ms_warning("linphone_call_send_dtmfs(): a DTMF sequence is already in place, canceling DTMF sequence.");
|
||||
return -2;
|
||||
}
|
||||
if (dtmfs != NULL) {
|
||||
int delay_ms = lp_config_get_int(call->core->config,"net","dtmf_delay_ms",200);
|
||||
call->dtmf_sequence = ms_strdup(dtmfs);
|
||||
call->dtmfs_timer = sal_create_timer(call->core->sal, send_dtmf_handler, call, delay_ms, "DTMF sequence timer");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linphone_call_cancel_dtmfs(LinphoneCall *call) {
|
||||
/*nothing to do*/
|
||||
if (!call || !call->dtmfs_timer) return;
|
||||
|
||||
sal_cancel_timer(call->core->sal, call->dtmfs_timer);
|
||||
belle_sip_object_unref(call->dtmfs_timer);
|
||||
call->dtmfs_timer = NULL;
|
||||
if (call->dtmf_sequence != NULL) {
|
||||
ms_free(call->dtmf_sequence);
|
||||
call->dtmf_sequence = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ortp/telephonyevents.h>
|
||||
#include <ortp/zrtp.h>
|
||||
#include <mediastreamer2/zrtp.h>
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include "mediastreamer2/mseventqueue.h"
|
||||
#include "mediastreamer2/msvolume.h"
|
||||
|
|
@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#define COMPRESSED_LOG_COLLECTION_EXTENSION "gz"
|
||||
#ifdef WIN32
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
|
@ -64,7 +65,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define SET_BINARY_MODE(file)
|
||||
#endif
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#define COMPRESSED_LOG_COLLECTION_EXTENSION "txt"
|
||||
#endif
|
||||
#define LOG_COLLECTION_DEFAULT_PATH "."
|
||||
#define LOG_COLLECTION_DEFAULT_PREFIX "linphone"
|
||||
#define LOG_COLLECTION_DEFAULT_MAX_FILE_SIZE (10 * 1024 * 1024)
|
||||
|
||||
|
||||
/*#define UNSTANDART_GSM_11K 1*/
|
||||
|
||||
|
|
@ -78,8 +85,10 @@ static const char *liblinphone_version=
|
|||
#endif
|
||||
;
|
||||
static OrtpLogFunc liblinphone_log_func = NULL;
|
||||
static bool_t liblinphone_log_collection_enabled = FALSE;
|
||||
static const char * liblinphone_log_collection_path = ".";
|
||||
static LinphoneLogCollectionState liblinphone_log_collection_state = LinphoneLogCollectionDisabled;
|
||||
static char * liblinphone_log_collection_path = NULL;
|
||||
static char * liblinphone_log_collection_prefix = NULL;
|
||||
static int liblinphone_log_collection_max_file_size = LOG_COLLECTION_DEFAULT_MAX_FILE_SIZE;
|
||||
static ortp_mutex_t liblinphone_log_collection_mutex;
|
||||
static bool_t liblinphone_serialize_logs = FALSE;
|
||||
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime);
|
||||
|
|
@ -161,8 +170,6 @@ void linphone_core_set_log_level(OrtpLogLevel loglevel) {
|
|||
}
|
||||
}
|
||||
|
||||
#define LOGFILE_MAXSIZE (10 * 1024 * 1024)
|
||||
|
||||
static void linphone_core_log_collection_handler(OrtpLogLevel level, const char *fmt, va_list args) {
|
||||
const char *lname="undef";
|
||||
char *msg;
|
||||
|
|
@ -170,7 +177,7 @@ static void linphone_core_log_collection_handler(OrtpLogLevel level, const char
|
|||
char *log_filename2;
|
||||
FILE *log_file;
|
||||
struct timeval tp;
|
||||
struct tm *lt;
|
||||
struct tm *lt;
|
||||
time_t tt;
|
||||
struct stat statbuf;
|
||||
|
||||
|
|
@ -202,16 +209,20 @@ static void linphone_core_log_collection_handler(OrtpLogLevel level, const char
|
|||
}
|
||||
msg = ortp_strdup_vprintf(fmt, args);
|
||||
|
||||
log_filename1 = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone1.log");
|
||||
log_filename2 = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone2.log");
|
||||
log_filename1 = ortp_strdup_printf("%s/%s1.log",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX);
|
||||
log_filename2 = ortp_strdup_printf("%s/%s2.log",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX);
|
||||
ortp_mutex_lock(&liblinphone_log_collection_mutex);
|
||||
log_file = fopen(log_filename1, "a");
|
||||
fstat(fileno(log_file), &statbuf);
|
||||
if (statbuf.st_size > LOGFILE_MAXSIZE) {
|
||||
if (statbuf.st_size > liblinphone_log_collection_max_file_size) {
|
||||
fclose(log_file);
|
||||
log_file = fopen(log_filename2, "a");
|
||||
fstat(fileno(log_file), &statbuf);
|
||||
if (statbuf.st_size > LOGFILE_MAXSIZE) {
|
||||
if (statbuf.st_size > liblinphone_log_collection_max_file_size) {
|
||||
fclose(log_file);
|
||||
unlink(log_filename1);
|
||||
rename(log_filename2, log_filename1);
|
||||
|
|
@ -229,8 +240,46 @@ static void linphone_core_log_collection_handler(OrtpLogLevel level, const char
|
|||
ortp_free(msg);
|
||||
}
|
||||
|
||||
const char * linphone_core_get_log_collection_path(void) {
|
||||
if (liblinphone_log_collection_path != NULL) {
|
||||
return liblinphone_log_collection_path;
|
||||
}
|
||||
return LOG_COLLECTION_DEFAULT_PATH;
|
||||
}
|
||||
|
||||
void linphone_core_set_log_collection_path(const char *path) {
|
||||
liblinphone_log_collection_path = path;
|
||||
if (liblinphone_log_collection_path != NULL) {
|
||||
ms_free(liblinphone_log_collection_path);
|
||||
liblinphone_log_collection_path = NULL;
|
||||
}
|
||||
if (path != NULL) {
|
||||
liblinphone_log_collection_path = ms_strdup(path);
|
||||
}
|
||||
}
|
||||
|
||||
const char * linphone_core_get_log_collection_prefix(void) {
|
||||
if (liblinphone_log_collection_prefix != NULL) {
|
||||
return liblinphone_log_collection_prefix;
|
||||
}
|
||||
return LOG_COLLECTION_DEFAULT_PREFIX;
|
||||
}
|
||||
|
||||
void linphone_core_set_log_collection_prefix(const char *prefix) {
|
||||
if (liblinphone_log_collection_prefix != NULL) {
|
||||
ms_free(liblinphone_log_collection_prefix);
|
||||
liblinphone_log_collection_prefix = NULL;
|
||||
}
|
||||
if (prefix != NULL) {
|
||||
liblinphone_log_collection_prefix = ms_strdup(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
int linphone_core_get_log_collection_max_file_size(void) {
|
||||
return liblinphone_log_collection_max_file_size;
|
||||
}
|
||||
|
||||
void linphone_core_set_log_collection_max_file_size(int size) {
|
||||
liblinphone_log_collection_max_file_size = size;
|
||||
}
|
||||
|
||||
const char *linphone_core_get_log_collection_upload_server_url(LinphoneCore *core) {
|
||||
|
|
@ -241,25 +290,39 @@ void linphone_core_set_log_collection_upload_server_url(LinphoneCore *core, cons
|
|||
lp_config_set_string(core->config, "misc", "log_collection_upload_server_url", server_url);
|
||||
}
|
||||
|
||||
void linphone_core_enable_log_collection(bool_t enable) {
|
||||
if ((enable == TRUE) && (liblinphone_log_collection_enabled == FALSE)) {
|
||||
liblinphone_log_collection_enabled = TRUE;
|
||||
ortp_mutex_init(&liblinphone_log_collection_mutex, NULL);
|
||||
LinphoneLogCollectionState linphone_core_log_collection_enabled(void) {
|
||||
return liblinphone_log_collection_state;
|
||||
}
|
||||
|
||||
void linphone_core_enable_log_collection(LinphoneLogCollectionState state) {
|
||||
if (liblinphone_log_collection_state == state) return;
|
||||
|
||||
/* at first call of this function, set liblinphone_log_func to the current
|
||||
* ortp log function */
|
||||
if( liblinphone_log_func == NULL ){
|
||||
liblinphone_log_func = ortp_logv_out;
|
||||
}
|
||||
liblinphone_log_collection_state = state;
|
||||
if (state != LinphoneLogCollectionDisabled) {
|
||||
ortp_mutex_init(&liblinphone_log_collection_mutex, NULL);
|
||||
if (state == LinphoneLogCollectionEnabledWithoutPreviousLogHandler) {
|
||||
liblinphone_log_func = NULL;
|
||||
} else {
|
||||
liblinphone_log_func = ortp_logv_out;
|
||||
}
|
||||
ortp_set_log_handler(linphone_core_log_collection_handler);
|
||||
} else {
|
||||
liblinphone_log_collection_enabled = FALSE;
|
||||
ortp_set_log_handler(liblinphone_log_func);
|
||||
}
|
||||
}
|
||||
|
||||
static void delete_log_collection_upload_file(void) {
|
||||
#ifdef HAVE_ZLIB
|
||||
char *filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone_log.gz");
|
||||
#else
|
||||
char *filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone_log.gz");
|
||||
#endif
|
||||
char *filename = ms_strdup_printf("%s/%s_log.%s",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX,
|
||||
COMPRESSED_LOG_COLLECTION_EXTENSION);
|
||||
unlink(filename);
|
||||
ms_free(filename);
|
||||
}
|
||||
|
||||
static void process_io_error_upload_log_collection(void *data, const belle_sip_io_error_event_t *event) {
|
||||
|
|
@ -276,8 +339,6 @@ static void process_auth_requested_upload_log_collection(void *data, belle_sip_a
|
|||
delete_log_collection_upload_file();
|
||||
}
|
||||
|
||||
extern const char *multipart_boundary;
|
||||
|
||||
/**
|
||||
* Callback called when posting a log collection file to server (following rcs5.1 recommendation)
|
||||
*
|
||||
|
|
@ -293,18 +354,20 @@ static int log_collection_upload_on_send_body(belle_sip_user_body_handler_t *bh,
|
|||
LinphoneCore *core = (LinphoneCore *)data;
|
||||
|
||||
/* If we've not reach the end of file yet, fill the buffer with more data */
|
||||
if (offset < core->log_collection_upload_information->size) {
|
||||
if (offset < linphone_content_get_size(core->log_collection_upload_information)) {
|
||||
char *log_filename = ms_strdup_printf("%s/%s_log.%s",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX,
|
||||
COMPRESSED_LOG_COLLECTION_EXTENSION);
|
||||
#ifdef HAVE_ZLIB
|
||||
char *log_filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone_log.gz");
|
||||
FILE *log_file = fopen(log_filename, "rb");
|
||||
#else
|
||||
char *log_filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone_log.txt");
|
||||
FILE *log_file = fopen(log_filename, "r");
|
||||
#endif
|
||||
fseek(log_file, offset, SEEK_SET);
|
||||
*size = fread(buffer, 1, *size, log_file);
|
||||
fclose(log_file);
|
||||
ortp_free(log_filename);
|
||||
ms_free(log_filename);
|
||||
}
|
||||
|
||||
return BELLE_SIP_CONTINUE;
|
||||
|
|
@ -316,7 +379,7 @@ static int log_collection_upload_on_send_body(belle_sip_user_body_handler_t *bh,
|
|||
*/
|
||||
static void log_collection_upload_on_progress(belle_sip_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, size_t total) {
|
||||
LinphoneCore *core = (LinphoneCore *)data;
|
||||
linphone_core_notify_log_collection_upload_progress_indication(core, (size_t)(((double)offset / (double)total) * 100.0));
|
||||
linphone_core_notify_log_collection_upload_progress_indication(core, offset, total);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -341,29 +404,27 @@ static void process_response_from_post_file_log_collection(void *data, const bel
|
|||
belle_http_request_t *req;
|
||||
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;
|
||||
|
||||
linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateInProgress, NULL);
|
||||
|
||||
/* Temporary storage for the Content-disposition header value */
|
||||
first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", core->log_collection_upload_information->name);
|
||||
first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", linphone_content_get_name(core->log_collection_upload_information));
|
||||
|
||||
/* 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(core->log_collection_upload_information->size, NULL, NULL, log_collection_upload_on_send_body, core);
|
||||
first_part_bh = belle_sip_user_body_handler_new(linphone_content_get_size(core->log_collection_upload_information), NULL, NULL, log_collection_upload_on_send_body, core);
|
||||
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(core->log_collection_upload_information->type, core->log_collection_upload_information->subtype));
|
||||
belle_sip_body_handler_add_header((belle_sip_body_handler_t *)first_part_bh,
|
||||
(belle_sip_header_t *)belle_sip_header_content_type_create(linphone_content_get_type(core->log_collection_upload_information), linphone_content_get_subtype(core->log_collection_upload_information)));
|
||||
|
||||
/* Insert it in a multipart body handler which will manage the boundaries of multipart message */
|
||||
bh = belle_sip_multipart_body_handler_new(log_collection_upload_on_progress, core, (belle_sip_body_handler_t *)first_part_bh);
|
||||
ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version());
|
||||
content_type = belle_sip_strdup_printf("multipart/form-data; boundary=%s", multipart_boundary);
|
||||
uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core));
|
||||
req = belle_http_request_create("POST", uri, belle_sip_header_create("User-Agent", ua), belle_sip_header_create("Content-type", content_type), NULL);
|
||||
req = belle_http_request_create("POST", uri, belle_sip_header_create("User-Agent", ua), NULL);
|
||||
ms_free(ua);
|
||||
belle_sip_free(content_type);
|
||||
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh));
|
||||
cbs.process_response = process_response_from_post_file_log_collection;
|
||||
cbs.process_io_error = process_io_error_upload_log_collection;
|
||||
|
|
@ -444,17 +505,22 @@ static int prepare_log_collection_file_to_upload(const char *filename) {
|
|||
int ret = 0;
|
||||
|
||||
ortp_mutex_lock(&liblinphone_log_collection_mutex);
|
||||
output_filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, filename);
|
||||
output_file = COMPRESS_OPEN(output_filename, "a");
|
||||
output_filename = ms_strdup_printf("%s/%s",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, filename);
|
||||
output_file = COMPRESS_OPEN(output_filename, "w");
|
||||
if (output_file == NULL) goto error;
|
||||
input_filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone1.log");
|
||||
input_filename = ms_strdup_printf("%s/%s1.log",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX);
|
||||
input_file = fopen(input_filename, "r");
|
||||
if (input_file == NULL) goto error;
|
||||
ret = compress_file(input_file, output_file);
|
||||
if (ret < 0) goto error;
|
||||
fclose(input_file);
|
||||
ortp_free(input_filename);
|
||||
input_filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, "linphone2.log");
|
||||
ms_free(input_filename);
|
||||
input_filename = ms_strdup_printf("%s/%s2.log",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX);
|
||||
input_file = fopen(input_filename, "r");
|
||||
if (input_file != NULL) {
|
||||
ret = compress_file(input_file, output_file);
|
||||
|
|
@ -464,42 +530,47 @@ static int prepare_log_collection_file_to_upload(const char *filename) {
|
|||
error:
|
||||
if (input_file != NULL) fclose(input_file);
|
||||
if (output_file != NULL) COMPRESS_CLOSE(output_file);
|
||||
if (input_filename != NULL) ortp_free(input_filename);
|
||||
if (output_filename != NULL) ortp_free(output_filename);
|
||||
if (input_filename != NULL) ms_free(input_filename);
|
||||
if (output_filename != NULL) ms_free(output_filename);
|
||||
ortp_mutex_unlock(&liblinphone_log_collection_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t get_size_of_file_to_upload(const char *filename) {
|
||||
struct stat statbuf;
|
||||
char *output_filename = ortp_strdup_printf("%s/%s", liblinphone_log_collection_path, filename);
|
||||
char *output_filename = ms_strdup_printf("%s/%s",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, filename);
|
||||
FILE *output_file = fopen(output_filename, "rb");
|
||||
fstat(fileno(output_file), &statbuf);
|
||||
fclose(output_file);
|
||||
ms_free(output_filename);
|
||||
return statbuf.st_size;
|
||||
}
|
||||
|
||||
void linphone_core_upload_log_collection(LinphoneCore *core) {
|
||||
if ((core->log_collection_upload_information == NULL) && (linphone_core_get_log_collection_upload_server_url(core) != NULL) && (liblinphone_log_collection_enabled == TRUE)) {
|
||||
if ((core->log_collection_upload_information == NULL) && (linphone_core_get_log_collection_upload_server_url(core) != NULL) && (liblinphone_log_collection_state != LinphoneLogCollectionDisabled)) {
|
||||
/* 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;
|
||||
char *name;
|
||||
|
||||
core->log_collection_upload_information = (LinphoneContent *)malloc(sizeof(LinphoneContent));
|
||||
memset(core->log_collection_upload_information, 0, sizeof(LinphoneContent));
|
||||
#ifdef HAVE_ZLIB
|
||||
core->log_collection_upload_information->type = "application";
|
||||
core->log_collection_upload_information->subtype = "gzip";
|
||||
core->log_collection_upload_information->name = "linphone_log.gz";
|
||||
#else
|
||||
core->log_collection_upload_information->type = "text";
|
||||
core->log_collection_upload_information->subtype = "plain";
|
||||
core->log_collection_upload_information->name = "linphone_log.txt";
|
||||
linphone_content_set_type(core->log_collection_upload_information, "text");
|
||||
linphone_content_set_subtype(core->log_collection_upload_information,"plain");
|
||||
#endif
|
||||
if (prepare_log_collection_file_to_upload(core->log_collection_upload_information->name) < 0) return;
|
||||
core->log_collection_upload_information->size = get_size_of_file_to_upload(core->log_collection_upload_information->name);
|
||||
name = ms_strdup_printf("%s_log.%s",
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX,
|
||||
COMPRESSED_LOG_COLLECTION_EXTENSION);
|
||||
linphone_content_set_name(core->log_collection_upload_information, name);
|
||||
if (prepare_log_collection_file_to_upload(name) < 0) return;
|
||||
linphone_content_set_size(core->log_collection_upload_information, get_size_of_file_to_upload(name));
|
||||
uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core));
|
||||
req = belle_http_request_create("POST", uri, NULL, NULL, NULL);
|
||||
cbs.process_response = process_response_from_post_file_log_collection;
|
||||
|
|
@ -507,9 +578,44 @@ void linphone_core_upload_log_collection(LinphoneCore *core) {
|
|||
cbs.process_auth_requested = process_auth_requested_upload_log_collection;
|
||||
l = belle_http_request_listener_create_from_callbacks(&cbs, core);
|
||||
belle_http_provider_send_request(core->http_provider, req, l);
|
||||
ms_free(name);
|
||||
}
|
||||
}
|
||||
|
||||
char * linphone_core_compress_log_collection() {
|
||||
char *filename = NULL;
|
||||
if (liblinphone_log_collection_state == LinphoneLogCollectionDisabled) return NULL;
|
||||
filename = ms_strdup_printf("%s_log.%s",
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX,
|
||||
COMPRESSED_LOG_COLLECTION_EXTENSION);
|
||||
if (prepare_log_collection_file_to_upload(filename) < 0) {
|
||||
ms_free(filename);
|
||||
return NULL;
|
||||
}
|
||||
ms_free(filename);
|
||||
return ms_strdup_printf("%s/%s_log.%s",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX,
|
||||
COMPRESSED_LOG_COLLECTION_EXTENSION);
|
||||
}
|
||||
|
||||
void linphone_core_reset_log_collection() {
|
||||
char *filename;
|
||||
ortp_mutex_lock(&liblinphone_log_collection_mutex);
|
||||
delete_log_collection_upload_file();
|
||||
filename = ms_strdup_printf("%s/%s1.log",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX);
|
||||
unlink(filename);
|
||||
ms_free(filename);
|
||||
filename = ms_strdup_printf("%s/%s2.log",
|
||||
liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH,
|
||||
liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX);
|
||||
unlink(filename);
|
||||
ms_free(filename);
|
||||
ortp_mutex_unlock(&liblinphone_log_collection_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable logs in supplied FILE*.
|
||||
*
|
||||
|
|
@ -1025,6 +1131,7 @@ static void codecs_config_read(LinphoneCore *lc)
|
|||
}
|
||||
}
|
||||
audio_codecs=add_missing_codecs(lc,SalAudio,audio_codecs);
|
||||
|
||||
for (i=0;get_codec(lc,"video_codec",i,&pt);i++){
|
||||
if (pt){
|
||||
if (!ms_filter_codec_supported(pt->mime_type)){
|
||||
|
|
@ -1196,6 +1303,7 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc){
|
|||
*/
|
||||
void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
|
||||
lc->net_conf.download_bw=bw;
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
if (linphone_core_ready(lc)) lp_config_set_int(lc->config,"net","download_bw",bw);
|
||||
}
|
||||
|
||||
|
|
@ -1212,6 +1320,7 @@ void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
|
|||
*/
|
||||
void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw){
|
||||
lc->net_conf.upload_bw=bw;
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
if (linphone_core_ready(lc)) lp_config_set_int(lc->config,"net","upload_bw",bw);
|
||||
}
|
||||
|
||||
|
|
@ -1393,7 +1502,6 @@ static void linphone_core_start(LinphoneCore * lc) {
|
|||
misc_config_read(lc);
|
||||
ui_config_read(lc);
|
||||
#ifdef TUNNEL_ENABLED
|
||||
lc->tunnel=linphone_core_tunnel_new(lc);
|
||||
if (lc->tunnel) {
|
||||
linphone_tunnel_configure(lc->tunnel);
|
||||
}
|
||||
|
|
@ -1418,9 +1526,10 @@ void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState
|
|||
static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata)
|
||||
{
|
||||
const char *remote_provisioning_uri = NULL;
|
||||
LinphoneCoreVTable* local_vtable= linphone_vtable_new();
|
||||
const char *aac_fmtp162248, *aac_fmtp3244;
|
||||
LinphoneCoreVTable* local_vtable= linphone_core_v_table_new();
|
||||
ms_message("Initializing LinphoneCore %s", linphone_core_get_version());
|
||||
memset (lc, 0, sizeof (LinphoneCore));
|
||||
|
||||
lc->config=lp_config_ref(config);
|
||||
lc->data=userdata;
|
||||
lc->ringstream_autorelease=TRUE;
|
||||
|
|
@ -1464,17 +1573,29 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
linphone_core_assign_payload_type(lc,&payload_type_h264,102,"profile-level-id=42801F");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_vp8,103,NULL);
|
||||
|
||||
linphone_core_assign_payload_type(lc,&payload_type_theora,97,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_x_snow,-1,NULL);
|
||||
/* linphone_core_assign_payload_type(lc,&payload_type_theora,97,NULL); commented out to free 1 slot */
|
||||
/* linphone_core_assign_payload_type(lc,&payload_type_x_snow,-1,NULL); commented out to free 1 slot */
|
||||
/* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */
|
||||
/* linphone_core_assign_payload_type(&payload_type_h264,-1,"packetization-mode=1;profile-level-id=428014");*/
|
||||
#endif
|
||||
|
||||
/* For AAC, we use a config value to determine if we ought to support SBR. Since it is not offically supported
|
||||
* for the mpeg4-generic mime type, setting this flag to 1 will break compatibility with other clients. */
|
||||
if( lp_config_get_int(lc->config, "misc", "aac_use_sbr", FALSE) ) {
|
||||
ms_message("Using SBR for AAC");
|
||||
aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1";
|
||||
aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1";
|
||||
} else {
|
||||
aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5";
|
||||
aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5";
|
||||
}
|
||||
|
||||
|
||||
/*add all payload type for which we don't care about the number */
|
||||
linphone_core_assign_payload_type(lc,&payload_type_ilbc,-1,"mode=30");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_amr,-1,"octet-align=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_amrwb,-1,"octet-align=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_lpc1015,-1,NULL);
|
||||
/* linphone_core_assign_payload_type(lc,&payload_type_lpc1015,-1,NULL); commented out to free 1 slot */
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_16,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_24,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g726_32,-1,NULL);
|
||||
|
|
@ -1488,8 +1609,11 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
linphone_core_assign_payload_type(lc,&payload_type_silk_wb,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_silk_swb,-1,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_g729,18,"annexb=no");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_22k,-1,"config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_44k,-1,"config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; profile-level-id=76; sizeLength=13; streamType=5");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_16k,-1,aac_fmtp162248);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_22k,-1,aac_fmtp162248);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_32k,-1,aac_fmtp3244);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_44k,-1,aac_fmtp3244);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_aaceld_48k,-1,aac_fmtp162248);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; stereo=0; sprop-stereo=0");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_isac,-1,NULL);
|
||||
linphone_core_handle_static_payloads(lc);
|
||||
|
|
@ -1505,6 +1629,10 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
sal_set_user_pointer(lc->sal,lc);
|
||||
sal_set_callbacks(lc->sal,&linphone_sal_callbacks);
|
||||
|
||||
#ifdef TUNNEL_ENABLED
|
||||
lc->tunnel=linphone_core_tunnel_new(lc);
|
||||
#endif
|
||||
|
||||
lc->network_last_check = 0;
|
||||
lc->network_last_status = FALSE;
|
||||
|
||||
|
|
@ -1551,7 +1679,7 @@ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
|
|||
|
||||
LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, struct _LpConfig *config, void *userdata)
|
||||
{
|
||||
LinphoneCore *core = ms_new(LinphoneCore, 1);
|
||||
LinphoneCore *core = ms_new0(LinphoneCore, 1);
|
||||
linphone_core_init(core, vtable, config, userdata);
|
||||
return core;
|
||||
}
|
||||
|
|
@ -1702,6 +1830,7 @@ int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs)
|
|||
if (lc->codecs_conf.audio_codecs!=NULL) ms_list_free(lc->codecs_conf.audio_codecs);
|
||||
lc->codecs_conf.audio_codecs=codecs;
|
||||
_linphone_core_codec_config_write(lc);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2032,7 +2161,7 @@ static bool_t transports_unchanged(const LCSipTransports * tr1, const LCSipTrans
|
|||
tr2->tls_port==tr1->tls_port;
|
||||
}
|
||||
|
||||
static int apply_transports(LinphoneCore *lc){
|
||||
int _linphone_core_apply_transports(LinphoneCore *lc){
|
||||
Sal *sal=lc->sal;
|
||||
const char *anyaddr;
|
||||
LCSipTransports *tr=&lc->sip_conf.transports;
|
||||
|
|
@ -2046,20 +2175,26 @@ static int apply_transports(LinphoneCore *lc){
|
|||
anyaddr="0.0.0.0";
|
||||
|
||||
sal_unlisten_ports(sal);
|
||||
if (tr->udp_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
|
||||
transport_error(lc,"udp",tr->udp_port);
|
||||
if (lc->tunnel && linphone_tunnel_sip_enabled(lc->tunnel) && linphone_tunnel_get_activated(lc->tunnel)){
|
||||
if (sal_listen_port(sal,anyaddr,tr->udp_port,SalTransportUDP,TRUE)!=0){
|
||||
transport_error(lc,"udp+tunnel",tr->udp_port);
|
||||
}
|
||||
}
|
||||
if (tr->tcp_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
|
||||
transport_error(lc,"tcp",tr->tcp_port);
|
||||
}else{
|
||||
if (tr->udp_port!=0){
|
||||
if (sal_listen_port(sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
|
||||
transport_error(lc,"udp",tr->udp_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (linphone_core_sip_transport_supported(lc,LinphoneTransportTls)){
|
||||
if (tr->tls_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,TRUE)!=0){
|
||||
transport_error(lc,"tls",tr->tls_port);
|
||||
if (tr->tcp_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
|
||||
transport_error(lc,"tcp",tr->tcp_port);
|
||||
}
|
||||
}
|
||||
if (linphone_core_sip_transport_supported(lc,LinphoneTransportTls)){
|
||||
if (tr->tls_port!=0){
|
||||
if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,FALSE)!=0){
|
||||
transport_error(lc,"tls",tr->tls_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2112,7 +2247,7 @@ int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * t
|
|||
}
|
||||
|
||||
if (lc->sal==NULL) return 0;
|
||||
return apply_transports(lc);
|
||||
return _linphone_core_apply_transports(lc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2176,8 +2311,13 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){
|
|||
if (lc->sip_conf.ipv6_enabled!=val){
|
||||
lc->sip_conf.ipv6_enabled=val;
|
||||
if (lc->sal){
|
||||
/* we need to restart eXosip */
|
||||
apply_transports(lc);
|
||||
/* we need to update the sip stack */
|
||||
_linphone_core_apply_transports(lc);
|
||||
}
|
||||
/*update the localip immediately for the network monitor to avoid to "discover" later that we switched to ipv6*/
|
||||
linphone_core_get_local_ip(lc,AF_UNSPEC,NULL,lc->localip);
|
||||
if (linphone_core_ready(lc)){
|
||||
lp_config_set_int(lc->config,"sip","use_ipv6",(int)val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2431,8 +2571,8 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
if ( (lc->sip_conf.in_call_timeout > 0)
|
||||
&& (call->media_start_time != 0)
|
||||
&& ((curtime - call->media_start_time) > lc->sip_conf.in_call_timeout))
|
||||
&& (call->log->connected_date_time != 0)
|
||||
&& ((curtime - call->log->connected_date_time) > lc->sip_conf.in_call_timeout))
|
||||
{
|
||||
ms_message("in call timeout (%i)",lc->sip_conf.in_call_timeout);
|
||||
linphone_core_terminate_call(lc,call);
|
||||
|
|
@ -2661,6 +2801,10 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L
|
|||
LinphoneProxyConfig *found_noreg_cfg=NULL;
|
||||
LinphoneProxyConfig *default_cfg=lc->default_proxy;
|
||||
|
||||
if (linphone_address_get_domain(uri) == NULL) {
|
||||
ms_message("cannot seach for proxy for uri [%p] if no domain set. returning default",uri);
|
||||
return default_cfg;
|
||||
}
|
||||
/*return default proxy if it is matching the destination uri*/
|
||||
if (default_cfg){
|
||||
const char *domain=linphone_proxy_config_get_domain(default_cfg);
|
||||
|
|
@ -3086,28 +3230,15 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
char *barmesg;
|
||||
char *tmp;
|
||||
LinphoneAddress *from_parsed;
|
||||
SalMediaDescription *md;
|
||||
bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
|
||||
const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
|
||||
|
||||
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){
|
||||
if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){
|
||||
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
|
||||
linphone_call_set_state_base(call, LinphoneCallError, NULL,TRUE);
|
||||
linphone_call_unref(call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from_parsed=linphone_address_new(sal_op_get_from(call->op));
|
||||
linphone_address_clean(from_parsed);
|
||||
tmp=linphone_address_as_string(from_parsed);
|
||||
linphone_address_destroy(from_parsed);
|
||||
barmesg=ortp_strdup_printf("%s %s%s",tmp,_("is contacting you"),
|
||||
(sal_call_autoanswer_asked(call->op)) ?_(" and asked autoanswer."):_("."));
|
||||
(sal_call_autoanswer_asked(call->op)) ?_(" and asked autoanswer."):".");
|
||||
linphone_core_notify_show_interface(lc);
|
||||
linphone_core_notify_display_status(lc,barmesg);
|
||||
|
||||
|
|
@ -3260,15 +3391,20 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
**/
|
||||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
|
||||
int err=0;
|
||||
LinphoneCallState nextstate;
|
||||
#if defined(VIDEO_ENABLED) && defined(BUILD_UPNP)
|
||||
bool_t has_video = FALSE;
|
||||
#endif
|
||||
|
||||
switch(call->state){
|
||||
case LinphoneCallIncomingEarlyMedia:
|
||||
case LinphoneCallIncomingReceived:
|
||||
case LinphoneCallIncomingEarlyMedia:
|
||||
case LinphoneCallOutgoingRinging:
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
nextstate=LinphoneCallEarlyUpdating;
|
||||
break;
|
||||
case LinphoneCallStreamsRunning:
|
||||
/*these states are allowed for linphone_core_update_call()*/
|
||||
nextstate=LinphoneCallUpdating;
|
||||
break;
|
||||
default:
|
||||
ms_error("linphone_core_update_call() is not allowed in [%s] state",linphone_call_state_to_string(call->state));
|
||||
|
|
@ -3276,7 +3412,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
|
|||
}
|
||||
|
||||
if (params!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallUpdating,"Updating call");
|
||||
linphone_call_set_state(call,nextstate,"Updating call");
|
||||
#if defined(VIDEO_ENABLED) && defined(BUILD_UPNP)
|
||||
has_video = call->params->has_video;
|
||||
|
||||
|
|
@ -3510,7 +3646,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
|
|||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* check if this call is supposed to replace an already running one*/
|
||||
replaced=sal_call_get_replaces(call->op);
|
||||
if (replaced){
|
||||
|
|
@ -4556,7 +4692,10 @@ const char * linphone_core_get_ringback(const LinphoneCore *lc){
|
|||
}
|
||||
|
||||
/**
|
||||
* Enables or disable echo cancellation. Value is saved an used for subsequent calls
|
||||
* Enables or disable echo cancellation. Value is saved and used for subsequent calls.
|
||||
* This actually controls software echo cancellation. If hardware echo cancellation is available, it will be always used and activated for calls, regardless
|
||||
* of the value passed to this function.
|
||||
* When hardware echo cancellation is available, the software one is of course not activated.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
|
|
@ -4651,38 +4790,10 @@ bool_t linphone_core_agc_enabled(const LinphoneCore *lc){
|
|||
return lc->sound_conf.agc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the specified dtmf.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* This function only works during calls. The dtmf is automatically played to the user.
|
||||
* @param lc The LinphoneCore object
|
||||
* @param dtmf The dtmf name specified as a char, such as '0', '#' etc...
|
||||
*
|
||||
**/
|
||||
void linphone_core_send_dtmf(LinphoneCore *lc, char dtmf)
|
||||
{
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (call==NULL){
|
||||
ms_warning("linphone_core_send_dtmf(): no active call");
|
||||
return;
|
||||
}
|
||||
/*By default we send DTMF RFC2833 if we do not have enabled SIP_INFO but we can also send RFC2833 and SIP_INFO*/
|
||||
if (linphone_core_get_use_rfc2833_for_dtmf(lc)!=0 || linphone_core_get_use_info_for_dtmf(lc)==0)
|
||||
{
|
||||
/* In Band DTMF */
|
||||
if (call->audiostream!=NULL){
|
||||
audio_stream_send_dtmf(call->audiostream,dtmf);
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_error("we cannot send RFC2833 dtmf when we are not in communication");
|
||||
}
|
||||
}
|
||||
if (linphone_core_get_use_info_for_dtmf(lc)!=0){
|
||||
/* Out of Band DTMF (use INFO method) */
|
||||
sal_call_send_dtmf(call->op,dtmf);
|
||||
}
|
||||
linphone_call_send_dtmf(call, dtmf);
|
||||
}
|
||||
|
||||
void linphone_core_set_stun_server(LinphoneCore *lc, const char *server){
|
||||
|
|
@ -4833,11 +4944,11 @@ void linphone_core_set_firewall_policy(LinphoneCore *lc, LinphoneFirewallPolicy
|
|||
lp_config_set_string(lc->config,"net","firewall_policy",policy);
|
||||
}
|
||||
|
||||
ORTP_INLINE LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc) {
|
||||
LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc) {
|
||||
return _linphone_core_get_firewall_policy_with_lie(lc, FALSE);
|
||||
}
|
||||
|
||||
ORTP_INLINE LinphoneFirewallPolicy _linphone_core_get_firewall_policy(const LinphoneCore *lc) {
|
||||
LinphoneFirewallPolicy _linphone_core_get_firewall_policy(const LinphoneCore *lc) {
|
||||
return _linphone_core_get_firewall_policy_with_lie(lc, TRUE);
|
||||
}
|
||||
|
||||
|
|
@ -5544,10 +5655,14 @@ void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char
|
|||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
MSVideoSize linphone_core_get_preferred_video_size(LinphoneCore *lc){
|
||||
MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc){
|
||||
return lc->video_conf.vsize;
|
||||
}
|
||||
|
||||
char * linphone_core_get_preferred_video_size_name(const LinphoneCore *lc) {
|
||||
return ms_strdup(video_size_get_name(lc->video_conf.vsize));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the preferred frame rate for video.
|
||||
* Based on the available bandwidth constraints and network conditions, the video encoder
|
||||
|
|
@ -5933,6 +6048,8 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
if (i>=20) ms_warning("Cannot complete unregistration, giving up");
|
||||
}
|
||||
config->proxies=ms_list_free_with_data(config->proxies,(void (*)(void*)) _linphone_proxy_config_release);
|
||||
|
||||
config->deleted_proxies=ms_list_free_with_data(config->deleted_proxies,(void (*)(void*)) _linphone_proxy_config_release);
|
||||
|
||||
/*no longuer need to write proxy config if not changedlinphone_proxy_config_write_to_config_file(lc->config,NULL,i);*/ /*mark the end */
|
||||
|
||||
|
|
@ -6151,6 +6268,9 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
if(lc->rec_file!=NULL){
|
||||
ms_free(lc->rec_file);
|
||||
}
|
||||
if (lc->chat_db_file){
|
||||
ms_free(lc->chat_db_file);
|
||||
}
|
||||
if(lc->presence_model){
|
||||
linphone_presence_model_unref(lc->presence_model);
|
||||
}
|
||||
|
|
@ -6162,7 +6282,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
if (liblinphone_serialize_logs == TRUE) {
|
||||
ortp_set_log_thread_id(0);
|
||||
}
|
||||
ms_list_free_with_data(lc->vtables,(void (*)(void *))linphone_vtable_destroy);
|
||||
ms_list_free_with_data(lc->vtables,(void (*)(void *))linphone_core_v_table_destroy);
|
||||
}
|
||||
|
||||
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime){
|
||||
|
|
@ -6278,11 +6398,18 @@ bool_t linphone_core_can_we_add_call(LinphoneCore *lc)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void notify_soundcard_usage(LinphoneCore *lc, bool_t used){
|
||||
MSSndCard *card=lc->sound_conf.capt_sndcard;
|
||||
if (card && ms_snd_card_get_capabilities(card) & MS_SND_CARD_CAP_IS_SLOW){
|
||||
ms_message("Notifying soundcard that we don't need it anymore for calls.");
|
||||
ms_snd_card_set_usage_hint(card,used);
|
||||
}
|
||||
}
|
||||
|
||||
int linphone_core_add_call( LinphoneCore *lc, LinphoneCall *call)
|
||||
{
|
||||
if(linphone_core_can_we_add_call(lc))
|
||||
{
|
||||
if (linphone_core_can_we_add_call(lc)){
|
||||
if (lc->calls==NULL) notify_soundcard_usage(lc,TRUE);
|
||||
lc->calls = ms_list_append(lc->calls,call);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6305,6 +6432,7 @@ int linphone_core_del_call( LinphoneCore *lc, LinphoneCall *call)
|
|||
return -1;
|
||||
}
|
||||
lc->calls = the_calls;
|
||||
if (lc->calls==NULL) notify_soundcard_usage(lc,FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6392,6 +6520,7 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l
|
|||
* @param lc the LinphoneCore
|
||||
* @param call the call for which the parameters are to be build, or NULL in the case where the parameters are to be used for a new outgoing call.
|
||||
* @return a new LinphoneCallParams
|
||||
* @ingroup call_control
|
||||
*/
|
||||
LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call){
|
||||
if (!call) return linphone_core_create_default_call_parameters(lc);
|
||||
|
|
@ -6518,7 +6647,7 @@ typedef struct Hook{
|
|||
}Hook;
|
||||
|
||||
static Hook *hook_new(LinphoneCoreIterateHook hook, void *hook_data){
|
||||
Hook *h=ms_new(Hook,1);
|
||||
Hook *h=ms_new0(Hook,1);
|
||||
h->fun=hook;
|
||||
h->data=hook_data;
|
||||
return h;
|
||||
|
|
@ -6643,7 +6772,7 @@ bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, Linphone
|
|||
case LinphoneMediaEncryptionSRTP:
|
||||
return media_stream_srtp_supported();
|
||||
case LinphoneMediaEncryptionZRTP:
|
||||
return ortp_zrtp_available();
|
||||
return ms_zrtp_available();
|
||||
case LinphoneMediaEncryptionNone:
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -6660,7 +6789,7 @@ int linphone_core_set_media_encryption(LinphoneCore *lc, LinphoneMediaEncryption
|
|||
ret=-1;
|
||||
}else type="srtp";
|
||||
}else if (menc == LinphoneMediaEncryptionZRTP){
|
||||
if (!ortp_zrtp_available()){
|
||||
if (!ms_zrtp_available()){
|
||||
ms_warning("ZRTP not supported by library.");
|
||||
type="none";
|
||||
ret=-1;
|
||||
|
|
@ -6718,7 +6847,7 @@ void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp){
|
|||
sal_set_dscp(lc->sal,dscp);
|
||||
if (linphone_core_ready(lc)){
|
||||
lp_config_set_int_hex(lc->config,"sip","dscp",dscp);
|
||||
apply_transports(lc);
|
||||
_linphone_core_apply_transports(lc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6898,20 +7027,38 @@ int linphone_payload_type_get_channels(const LinphonePayloadType *pt) {
|
|||
return pt->channels;
|
||||
}
|
||||
|
||||
LinphoneCoreVTable *linphone_vtable_new() {
|
||||
LinphoneCoreVTable *linphone_core_v_table_new() {
|
||||
return ms_new0(LinphoneCoreVTable,1);
|
||||
}
|
||||
|
||||
void linphone_vtable_destroy(LinphoneCoreVTable* table) {
|
||||
void linphone_core_v_table_set_user_data(LinphoneCoreVTable *table, void *data) {
|
||||
if (table->user_data) {
|
||||
ms_free(table->user_data);
|
||||
}
|
||||
table->user_data = data;
|
||||
}
|
||||
|
||||
void* linphone_core_v_table_get_user_data(LinphoneCoreVTable *table) {
|
||||
return table->user_data;
|
||||
}
|
||||
|
||||
void linphone_core_v_table_destroy(LinphoneCoreVTable* table) {
|
||||
if (table->user_data) {
|
||||
ms_free(table->user_data);
|
||||
}
|
||||
ms_free(table);
|
||||
}
|
||||
|
||||
LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) {
|
||||
return lc->current_vtable;
|
||||
}
|
||||
|
||||
#define NOTIFY_IF_EXIST(function_name) \
|
||||
MSList* iterator; \
|
||||
ms_message ("Linphone core [%p] notifying [%s]",lc,#function_name);\
|
||||
for (iterator=lc->vtables; iterator!=NULL; iterator=iterator->next) \
|
||||
if (((LinphoneCoreVTable*)(iterator->data))->function_name)\
|
||||
if ((lc->current_vtable=((LinphoneCoreVTable*)(iterator->data)))->function_name)\
|
||||
((LinphoneCoreVTable*)(iterator->data))->function_name
|
||||
|
||||
void linphone_core_notify_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
|
||||
NOTIFY_IF_EXIST(global_state_changed)(lc,gstate,message);
|
||||
}
|
||||
|
|
@ -6963,8 +7110,8 @@ void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessa
|
|||
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) {
|
||||
NOTIFY_IF_EXIST(file_transfer_send)(lc,message,content,buff,size);
|
||||
}
|
||||
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress) {
|
||||
NOTIFY_IF_EXIST(file_transfer_progress_indication)(lc,message,content,progress);
|
||||
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) {
|
||||
NOTIFY_IF_EXIST(file_transfer_progress_indication)(lc,message,content,offset,total);
|
||||
}
|
||||
void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
|
||||
NOTIFY_IF_EXIST(is_composing_received)(lc,room);
|
||||
|
|
@ -7012,8 +7159,8 @@ void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent
|
|||
void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) {
|
||||
NOTIFY_IF_EXIST(log_collection_upload_state_changed)(lc, state, info);
|
||||
}
|
||||
void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t progress) {
|
||||
NOTIFY_IF_EXIST(log_collection_upload_progress_indication)(lc, progress);
|
||||
void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t offset, size_t total) {
|
||||
NOTIFY_IF_EXIST(log_collection_upload_progress_indication)(lc, offset, total);
|
||||
}
|
||||
void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable) {
|
||||
ms_message("Vtable [%p] registered on core [%p]",lc,vtable);
|
||||
|
|
|
|||
|
|
@ -126,26 +126,6 @@ typedef struct SalAddress LinphoneAddress;
|
|||
|
||||
typedef struct belle_sip_dict LinphoneDictionary;
|
||||
|
||||
/**
|
||||
* The LinphoneContent struct holds data that can be embedded in a signaling message.
|
||||
* @ingroup misc
|
||||
**/
|
||||
struct _LinphoneContent{
|
||||
char *type; /**<mime type for the data, for example "application"*/
|
||||
char *subtype; /**<mime subtype for the data, for example "html"*/
|
||||
void *data; /**<the actual data buffer, usually a string. Null when provided by callbacks #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb*/
|
||||
size_t size; /**<the size of the data buffer, excluding null character despite null character is always set for convenience.
|
||||
When provided by callback #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb, it states the total number of bytes of the transfered file*/
|
||||
char *encoding; /**<The encoding of the data buffer, for example "gzip"*/
|
||||
char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias to the LinphoneContent struct.
|
||||
* @ingroup misc
|
||||
**/
|
||||
typedef struct _LinphoneContent LinphoneContent;
|
||||
|
||||
/**
|
||||
* The LinphoneCall object represents a call issued or received by the LinphoneCore
|
||||
* @ingroup call_control
|
||||
|
|
@ -386,15 +366,17 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
|
|||
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonefriend.h"
|
||||
#include "event.h"
|
||||
#include "call_log.h"
|
||||
#include "call_params.h"
|
||||
#include "content.h"
|
||||
#include "event.h"
|
||||
#include "linphonefriend.h"
|
||||
#else
|
||||
#include "linphone/linphonefriend.h"
|
||||
#include "linphone/event.h"
|
||||
#include "linphone/call_log.h"
|
||||
#include "linphone/call_params.h"
|
||||
#include "linphone/content.h"
|
||||
#include "linphone/event.h"
|
||||
#include "linphone/linphonefriend.h"
|
||||
#endif
|
||||
|
||||
LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr);
|
||||
|
|
@ -418,6 +400,9 @@ LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,Linphon
|
|||
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_set_password(LinphoneAddress *addr, const char *passwd);
|
||||
LINPHONE_PUBLIC const char *linphone_address_get_password(const LinphoneAddress *addr);
|
||||
LINPHONE_PUBLIC void linphone_address_set_header(LinphoneAddress *addr, const char *header_name, const char *header_value);
|
||||
LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u);
|
||||
|
||||
/**
|
||||
|
|
@ -481,7 +466,7 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy;
|
|||
* @ingroup initializing
|
||||
**/
|
||||
enum _LinphoneIceState{
|
||||
LinphoneIceStateNotActivated, /**< ICE has not been activated for this call */
|
||||
LinphoneIceStateNotActivated, /**< ICE has not been activated for this call or stream*/
|
||||
LinphoneIceStateFailed, /**< ICE processing has failed */
|
||||
LinphoneIceStateInProgress, /**< ICE process is in progress */
|
||||
LinphoneIceStateHostConnection, /**< ICE has established a direct connection to the remote host */
|
||||
|
|
@ -495,6 +480,8 @@ enum _LinphoneIceState{
|
|||
**/
|
||||
typedef enum _LinphoneIceState LinphoneIceState;
|
||||
|
||||
LINPHONE_PUBLIC const char *linphone_ice_state_to_string(LinphoneIceState state);
|
||||
|
||||
/**
|
||||
* Enum describing uPnP states.
|
||||
* @ingroup initializing
|
||||
|
|
@ -595,29 +582,24 @@ 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);
|
||||
void linphone_player_destroy(LinphonePlayer *obj);
|
||||
|
||||
/**
|
||||
* @brief Create an independent media file player.
|
||||
* This player support WAVE and MATROSKA formats.
|
||||
* @param lc A LinphoneCore
|
||||
* @param lc A LinphoneCore object
|
||||
* @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
|
||||
* @param window_id Pointer on the drawing window
|
||||
* @param window_id Id of the drawing window. Depend of video out
|
||||
* @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, void *window_id);
|
||||
|
||||
/**
|
||||
* @brief Destroy a file player
|
||||
* @param obj File player to destroy
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_file_player_destroy(LinphonePlayer *obj);
|
||||
LINPHONE_PUBLIC LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, MSSndCard *snd_card, const char *video_out, unsigned long window_id);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
LINPHONE_PUBLIC bool_t linphone_local_player_matroska_supported(void);
|
||||
|
||||
/**
|
||||
* LinphoneCallState enum represents the different state a call can reach into.
|
||||
|
|
@ -643,7 +625,9 @@ typedef enum _LinphoneCallState{
|
|||
LinphoneCallUpdatedByRemote, /**<The call's parameters change is requested by remote end, used for example when video is added by remote */
|
||||
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
|
||||
LinphoneCallUpdating, /**<A call update has been initiated by us */
|
||||
LinphoneCallReleased /**< The call object is no more retained by the core */
|
||||
LinphoneCallReleased, /**< The call object is no more retained by the core */
|
||||
LinphoneCallEarlyUpdatedByRemote, /*<The call is updated by remote while not yet answered (early dialog SIP UPDATE received).*/
|
||||
LinphoneCallEarlyUpdating /*<We are updating the call while not yet answered (early dialog SIP UPDATE sent)*/
|
||||
} LinphoneCallState;
|
||||
|
||||
LINPHONE_PUBLIC const char *linphone_call_state_to_string(LinphoneCallState cs);
|
||||
|
|
@ -733,6 +717,38 @@ LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_fac
|
|||
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);
|
||||
LINPHONE_PUBLIC bool_t linphone_call_media_in_progress(LinphoneCall *call);
|
||||
/**
|
||||
* Send the specified dtmf.
|
||||
*
|
||||
* The dtmf is automatically played to the user.
|
||||
* @param call The LinphoneCall object
|
||||
* @param dtmf The dtmf name specified as a char, such as '0', '#' etc...
|
||||
* @returns 0 if successful, -1 on error.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_call_send_dtmf(LinphoneCall *lc,char dtmf);
|
||||
|
||||
/**
|
||||
* Send a list of dtmf.
|
||||
*
|
||||
* The dtmfs are automatically sent to remote, separated by some needed customizable delay.
|
||||
* Sending is canceled if the call state changes to something not LinphoneCallStreamsRunning.
|
||||
* @param call The LinphoneCall object
|
||||
* @param dtmfs A dtmf sequence such as '123#123123'
|
||||
* @returns -2 if there is already a DTMF sequence, -1 if call is not ready, 0 otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_call_send_dtmfs(LinphoneCall *call,char *dtmfs);
|
||||
|
||||
/**
|
||||
* Stop current DTMF sequence sending.
|
||||
*
|
||||
* Please note that some DTMF could be already sent,
|
||||
* depending on when this function call is delayed from #linphone_call_send_dtmfs. This
|
||||
* function will be automatically called if call state change to anything but LinphoneCallStreamsRunning.
|
||||
*
|
||||
* @param call The LinphoneCall object
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_cancel_dtmfs(LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Return TRUE if this call is currently part of a conference
|
||||
|
|
@ -1285,7 +1301,12 @@ struct _LinphoneChatRoom;
|
|||
*/
|
||||
|
||||
/**
|
||||
* A chat room message to old content to be sent.
|
||||
* An object to handle the callbacks for the handling a LinphoneChatMessage objects.
|
||||
*/
|
||||
typedef struct _LinphoneChatMessageCbs LinphoneChatMessageCbs;
|
||||
|
||||
/**
|
||||
* A chat room message to hold content to be sent.
|
||||
* <br> Can be created by linphone_chat_room_create_message().
|
||||
*/
|
||||
typedef struct _LinphoneChatMessage LinphoneChatMessage;
|
||||
|
|
@ -1302,9 +1323,10 @@ typedef struct _LinphoneChatRoom LinphoneChatRoom;
|
|||
typedef enum _LinphoneChatMessageState {
|
||||
LinphoneChatMessageStateIdle, /**< Initial state */
|
||||
LinphoneChatMessageStateInProgress, /**< Delivery in progress */
|
||||
LinphoneChatMessageStateDelivered, /**< Message succesffully delivered an acknoleged by remote end point */
|
||||
LinphoneChatMessageStateDelivered, /**< Message successfully delivered and acknowledged by remote end point */
|
||||
LinphoneChatMessageStateNotDelivered, /**< Message was not delivered */
|
||||
LinphoneChatMessageStateFileTransferError /**< Message was received(and acknowledged) but cannot get file from server */
|
||||
LinphoneChatMessageStateFileTransferError, /**< Message was received(and acknowledged) but cannot get file from server */
|
||||
LinphoneChatMessageStateFileTransferDone /**< File transfer has been completed successfully. */
|
||||
} LinphoneChatMessageState;
|
||||
|
||||
/**
|
||||
|
|
@ -1315,6 +1337,46 @@ typedef enum _LinphoneChatMessageState {
|
|||
*/
|
||||
typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud);
|
||||
|
||||
/**
|
||||
* Call back used to notify message delivery status
|
||||
* @param msg #LinphoneChatMessage object
|
||||
* @param status LinphoneChatMessageState
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageMsgStateChangedCb)(LinphoneChatMessage* msg, LinphoneChatMessageState state);
|
||||
|
||||
/**
|
||||
* File transfer receive callback prototype. This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file.
|
||||
*
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent incoming content information
|
||||
* @param buff pointer to the received data
|
||||
* @param size number of bytes to be read from buff. 0 means end of file.
|
||||
*
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageFileTransferRecvCb)(LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size);
|
||||
|
||||
/**
|
||||
* File transfer send callback prototype. This function is called by the core upon an outgoing File transfer is started. This function is called until size is set to 0.
|
||||
* <br> a #LinphoneContent with a size equal zero
|
||||
*
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent outgoing content
|
||||
* @param buff pointer to the buffer where data chunk shall be written by the app
|
||||
* @param size as input value, it represents the number of bytes expected by the framework. As output value, it means the number of bytes wrote by the application in the buffer. 0 means end of file.
|
||||
*
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size);
|
||||
|
||||
/**
|
||||
* File transfer progress indication callback prototype.
|
||||
*
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent incoming content information
|
||||
* @param offset The number of bytes sent/received since the beginning of the transfer.
|
||||
* @param total The total number of bytes to be sent/received.
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageFileTransferProgressIndicationCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path);
|
||||
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);
|
||||
|
|
@ -1365,6 +1427,7 @@ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_mes
|
|||
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb,void* ud);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
LINPHONE_PUBLIC MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr);
|
||||
|
|
@ -1425,8 +1488,9 @@ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(cons
|
|||
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);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage* msg);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb, void* ud);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_download_file(LinphoneChatMessage *message);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage* msg);
|
||||
LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data);
|
||||
LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* message);
|
||||
|
|
@ -1443,6 +1507,23 @@ LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* me
|
|||
LINPHONE_PUBLIC unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage* message);
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg);
|
||||
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath);
|
||||
LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg);
|
||||
|
||||
LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_unref(LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void *linphone_chat_message_cbs_get_user_data(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_user_data(LinphoneChatMessageCbs *cbs, void *ud);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageMsgStateChangedCb cb);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageFileTransferRecvCb cb);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageFileTransferSendCb cb);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageFileTransferProgressIndicationCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
@ -1482,7 +1563,7 @@ typedef enum _LinphoneCoreLogCollectionUploadState {
|
|||
* @param gstate the global state
|
||||
* @param message informational message.
|
||||
*/
|
||||
typedef void (*LinphoneCoreGlobalStateChangedCb )(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
typedef void (*LinphoneCoreGlobalStateChangedCb)(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
/**
|
||||
* Call state notification callback.
|
||||
* @param lc the LinphoneCore
|
||||
|
|
@ -1608,10 +1689,10 @@ typedef void (*LinphoneCoreFileTransferSendCb)(LinphoneCore *lc, LinphoneChatMes
|
|||
* @param lc #LinphoneCore object
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent incoming content information
|
||||
* @param progress number of bytes sent/received from the begening of the transfer.
|
||||
*
|
||||
* @param offset The number of bytes sent/received since the beginning of the transfer.
|
||||
* @param total The total number of bytes to be sent/received.
|
||||
*/
|
||||
typedef void (*LinphoneCoreFileTransferProgressIndicationCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress);
|
||||
typedef void (*LinphoneCoreFileTransferProgressIndicationCb)(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
|
||||
|
||||
/**
|
||||
* Is composing notification callback prototype.
|
||||
|
|
@ -1694,7 +1775,7 @@ typedef void (*LinphoneCoreLogCollectionUploadStateChangedCb)(LinphoneCore *lc,
|
|||
* @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);
|
||||
typedef void (*LinphoneCoreLogCollectionUploadProgressIndicationCb)(LinphoneCore *lc, size_t offset, size_t total);
|
||||
|
||||
/**
|
||||
* This structure holds all callbacks that the application should implement.
|
||||
|
|
@ -1727,25 +1808,48 @@ typedef struct _LinphoneCoreVTable{
|
|||
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 */
|
||||
LinphoneCoreFileTransferRecvCb file_transfer_recv; /**< @deprecated Callback to store file received attached to a #LinphoneChatMessage */
|
||||
LinphoneCoreFileTransferSendCb file_transfer_send; /**< @deprecated Callback to collect file chunk to be sent for a #LinphoneChatMessage */
|
||||
LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**< @deprecated 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 */
|
||||
void *user_data;
|
||||
} LinphoneCoreVTable;
|
||||
|
||||
/**
|
||||
* Instantiate a vtable with all argument set to NULL
|
||||
* Instantiate a vtable with all arguments set to NULL
|
||||
* @returns newly allocated vtable
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCoreVTable *linphone_vtable_new();
|
||||
LINPHONE_PUBLIC LinphoneCoreVTable *linphone_core_v_table_new();
|
||||
|
||||
/**
|
||||
* destroy a vtable.
|
||||
* Sets a user data pointer in the vtable.
|
||||
* @param table the vtable
|
||||
* @param data the user data to attach
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_v_table_set_user_data(LinphoneCoreVTable *table, void *data);
|
||||
|
||||
/**
|
||||
* Gets a user data pointer in the vtable.
|
||||
* @param table the vtable
|
||||
* @returns the data attached to the vtable
|
||||
*/
|
||||
LINPHONE_PUBLIC void* linphone_core_v_table_get_user_data(LinphoneCoreVTable *table);
|
||||
|
||||
/**
|
||||
* Gets the current VTable.
|
||||
* This is meant only to be called from a callback to be able to get the user_data associated with the vtable that called the callback.
|
||||
* @param lc the linphonecore
|
||||
* @returns the vtable that called the last callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Destroy a vtable.
|
||||
* @param vtable to be destroyed
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_vtable_destroy(LinphoneCoreVTable* table);
|
||||
LINPHONE_PUBLIC void linphone_core_v_table_destroy(LinphoneCoreVTable* table);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
@ -1753,8 +1857,8 @@ LINPHONE_PUBLIC void linphone_vtable_destroy(LinphoneCoreVTable* table);
|
|||
|
||||
typedef struct _LCCallbackObj
|
||||
{
|
||||
LinphoneCoreCbFunc _func;
|
||||
void * _user_data;
|
||||
LinphoneCoreCbFunc _func;
|
||||
void * _user_data;
|
||||
}LCCallbackObj;
|
||||
|
||||
|
||||
|
|
@ -1780,12 +1884,32 @@ typedef void * (*LinphoneCoreWaitingCallback)(LinphoneCore *lc, void *context, L
|
|||
|
||||
/* THE main API */
|
||||
|
||||
typedef enum _LinphoneLogCollectionState {
|
||||
LinphoneLogCollectionDisabled,
|
||||
LinphoneLogCollectionEnabled,
|
||||
LinphoneLogCollectionEnabledWithoutPreviousLogHandler
|
||||
} LinphoneLogCollectionState;
|
||||
|
||||
/**
|
||||
* Tells whether the linphone core log collection is enabled.
|
||||
* @ingroup misc
|
||||
* @returns The state of the linphone core log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneLogCollectionState linphone_core_log_collection_enabled(void);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param[in] state LinphoneLogCollectionState value telling whether to enable log collection or not.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_enable_log_collection(bool_t enable);
|
||||
LINPHONE_PUBLIC void linphone_core_enable_log_collection(LinphoneLogCollectionState state);
|
||||
|
||||
/**
|
||||
* Get the path where the log files will be written for log collection.
|
||||
* @ingroup misc
|
||||
* @returns The path where the log files will be written.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_log_collection_path(void);
|
||||
|
||||
/**
|
||||
* Set the path where the log files will be written for log collection.
|
||||
|
|
@ -1794,6 +1918,38 @@ LINPHONE_PUBLIC void linphone_core_enable_log_collection(bool_t enable);
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_log_collection_path(const char *path);
|
||||
|
||||
/**
|
||||
* Get the prefix of the filenames that will be used for log collection.
|
||||
* @ingroup misc
|
||||
* @returns The prefix of the filenames used for log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_log_collection_prefix(void);
|
||||
|
||||
/**
|
||||
* Set the prefix of the filenames that will be used for log collection.
|
||||
* @ingroup misc
|
||||
* @param[in] prefix The prefix to use for the filenames for log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_log_collection_prefix(const char *prefix);
|
||||
|
||||
/**
|
||||
* Get the max file size in bytes of the files used for log collection.
|
||||
* @ingroup misc
|
||||
* @returns The max file size in bytes of the files used for log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_core_get_log_collection_max_file_size(void);
|
||||
|
||||
/**
|
||||
* Set the max file size in bytes of the files used for log collection.
|
||||
* Warning: this function should only not be used to change size
|
||||
* dynamically but instead only before calling @see
|
||||
* linphone_core_enable_log_collection. If you increase max size
|
||||
* on runtime, logs chronological order COULD be broken.
|
||||
* @ingroup misc
|
||||
* @param[in] size The max file size in bytes of the files used for log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_log_collection_max_file_size(int size);
|
||||
|
||||
/**
|
||||
* Set the url of the server where to upload the collected log files.
|
||||
* @ingroup misc
|
||||
|
|
@ -1809,6 +1965,19 @@ LINPHONE_PUBLIC void linphone_core_set_log_collection_upload_server_url(Linphone
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_upload_log_collection(LinphoneCore *core);
|
||||
|
||||
/**
|
||||
* Compress the log collection in a single file.
|
||||
* @ingroup misc
|
||||
* @return The path of the compressed log collection file (to be freed calling ms_free()).
|
||||
*/
|
||||
LINPHONE_PUBLIC char * linphone_core_compress_log_collection();
|
||||
|
||||
/**
|
||||
* Reset the log collection by removing the log files.
|
||||
* @ingroup misc
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_reset_log_collection();
|
||||
|
||||
/**
|
||||
* Define a log handler.
|
||||
*
|
||||
|
|
@ -1983,6 +2152,16 @@ LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_call_params(LinphoneCor
|
|||
|
||||
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address);
|
||||
|
||||
/**
|
||||
* Send the specified dtmf.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
* @deprecated Use #linphone_call_send_dtmf instead.
|
||||
* This function only works during calls. The dtmf is automatically played to the user.
|
||||
* @param lc The LinphoneCore object
|
||||
* @param dtmf The dtmf name specified as a char, such as '0', '#' etc...
|
||||
*
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf);
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact);
|
||||
|
|
@ -2612,7 +2791,14 @@ LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MS
|
|||
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 MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Get the name of the current preferred video size for sending.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns A string containing the name of the current preferred video size (to be freed with ms_free()).
|
||||
*/
|
||||
LINPHONE_PUBLIC char * linphone_core_get_preferred_video_size_name(const 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);
|
||||
LINPHONE_PUBLIC float linphone_core_get_preferred_framerate(LinphoneCore *lc);
|
||||
|
|
@ -2687,7 +2873,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 );
|
||||
LINPHONE_PUBLIC int linphone_core_get_device_rotation(LinphoneCore *lc );
|
||||
LINPHONE_PUBLIC void linphone_core_set_device_rotation(LinphoneCore *lc, int rotation);
|
||||
|
||||
/**
|
||||
|
|
@ -3027,6 +3213,8 @@ LINPHONE_PUBLIC void linphone_core_set_avpf_mode(LinphoneCore *lc, LinphoneAVPFM
|
|||
|
||||
LINPHONE_PUBLIC LinphoneAVPFMode linphone_core_get_avpf_mode(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_avpf_rr_interval(LinphoneCore *lc, int interval);
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_get_avpf_rr_interval(const LinphoneCore *lc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
98
coreapi/localplayer.c
Normal file
98
coreapi/localplayer.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 - 2010 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
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"
|
||||
#include <mediastreamer2/msmediaplayer.h>
|
||||
#include <mediastreamer2/mssndcard.h>
|
||||
|
||||
static int _local_player_open(LinphonePlayer *obj, const char *filename);
|
||||
static int _local_player_start(LinphonePlayer *obj);
|
||||
static int _local_player_pause(LinphonePlayer *obj);
|
||||
static int _local_player_seek(LinphonePlayer *obj, int time_ms);
|
||||
static MSPlayerState _local_player_get_state(LinphonePlayer *obj);
|
||||
static int _local_player_get_duration(LinphonePlayer *obj);
|
||||
static int _local_player_get_current_position(LinphonePlayer *obj);
|
||||
static void _local_player_close(LinphonePlayer *obj);
|
||||
static void _local_player_destroy(LinphonePlayer *obj);
|
||||
static void _local_player_eof_callback(void *user_data);
|
||||
|
||||
LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, MSSndCard *snd_card, const char *video_out, unsigned long window_id) {
|
||||
LinphonePlayer *obj = ms_new0(LinphonePlayer, 1);
|
||||
if(snd_card == NULL) snd_card = lc->sound_conf.ring_sndcard;
|
||||
if(video_out == NULL) video_out = linphone_core_get_video_display_filter(lc);
|
||||
obj->impl = ms_media_player_new(snd_card, video_out, window_id);
|
||||
obj->open = _local_player_open;
|
||||
obj->start = _local_player_start;
|
||||
obj->pause = _local_player_pause;
|
||||
obj->seek = _local_player_seek;
|
||||
obj->get_state = _local_player_get_state;
|
||||
obj->get_duration = _local_player_get_duration;
|
||||
obj->get_position = _local_player_get_current_position;
|
||||
obj->close = _local_player_close;
|
||||
obj->destroy = _local_player_destroy;
|
||||
ms_media_player_set_eof_callback((MSMediaPlayer *)obj->impl, _local_player_eof_callback, obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool_t linphone_local_player_matroska_supported(void) {
|
||||
return ms_media_player_matroska_supported();
|
||||
}
|
||||
|
||||
static int _local_player_open(LinphonePlayer *obj, const char *filename) {
|
||||
return ms_media_player_open((MSMediaPlayer *)obj->impl, filename) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int _local_player_start(LinphonePlayer *obj) {
|
||||
return ms_media_player_start((MSMediaPlayer *)obj->impl) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int _local_player_pause(LinphonePlayer *obj) {
|
||||
ms_media_player_pause((MSMediaPlayer *)obj->impl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _local_player_seek(LinphonePlayer *obj, int time_ms) {
|
||||
return ms_media_player_seek((MSMediaPlayer *)obj->impl, time_ms) ? 0 : -1;
|
||||
}
|
||||
|
||||
static MSPlayerState _local_player_get_state(LinphonePlayer *obj) {
|
||||
return ms_media_player_get_state((MSMediaPlayer *)obj->impl);
|
||||
}
|
||||
|
||||
static int _local_player_get_duration(LinphonePlayer *obj) {
|
||||
return ms_media_player_get_duration((MSMediaPlayer *)obj->impl);
|
||||
}
|
||||
|
||||
static int _local_player_get_current_position(LinphonePlayer *obj) {
|
||||
return ms_media_player_get_current_position((MSMediaPlayer *)obj->impl);
|
||||
}
|
||||
|
||||
static void _local_player_destroy(LinphonePlayer *obj) {
|
||||
ms_media_player_free((MSMediaPlayer *)obj->impl);
|
||||
_linphone_player_destroy(obj);
|
||||
}
|
||||
|
||||
static void _local_player_close(LinphonePlayer *obj) {
|
||||
ms_media_player_close((MSMediaPlayer *)obj->impl);
|
||||
}
|
||||
|
||||
static void _local_player_eof_callback(void *user_data) {
|
||||
LinphonePlayer *obj = (LinphonePlayer *)user_data;
|
||||
obj->cb(obj, obj->user_data);
|
||||
}
|
||||
|
|
@ -49,7 +49,9 @@
|
|||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define RENAME_REQUIRES_NONEXISTENT_NEW_PATH 1
|
||||
#endif
|
||||
|
||||
#define lp_new0(type,n) (type*)calloc(sizeof(type),n)
|
||||
|
||||
|
|
@ -77,6 +79,7 @@ struct _LpConfig{
|
|||
int refcnt;
|
||||
FILE *file;
|
||||
char *filename;
|
||||
char *tmpfilename;
|
||||
MSList *sections;
|
||||
int modified;
|
||||
int readonly;
|
||||
|
|
@ -349,22 +352,34 @@ LpConfig *lp_config_new_with_factory(const char *config_filename, const char *fa
|
|||
if (config_filename!=NULL){
|
||||
ms_message("Using (r/w) config information from %s", config_filename);
|
||||
lpconfig->filename=ortp_strdup(config_filename);
|
||||
lpconfig->file=fopen(config_filename,"r+");
|
||||
lpconfig->tmpfilename=ortp_strdup_printf("%s.tmp",config_filename);
|
||||
|
||||
#if !defined(WIN32)
|
||||
{
|
||||
struct stat fileStat;
|
||||
if ((stat(config_filename,&fileStat) == 0) && (S_ISREG(fileStat.st_mode))) {
|
||||
/* make existing configuration files non-group/world-accessible */
|
||||
if (chmod(config_filename, S_IRUSR | S_IWUSR) == -1) {
|
||||
ms_warning("unable to correct permissions on "
|
||||
"configuration file: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*WIN32*/
|
||||
/*open with r+ to check if we can write on it later*/
|
||||
lpconfig->file=fopen(lpconfig->filename,"r+");
|
||||
#ifdef RENAME_REQUIRES_NONEXISTENT_NEW_PATH
|
||||
if (lpconfig->file==NULL){
|
||||
lpconfig->file=fopen(lpconfig->tmpfilename,"r+");
|
||||
if (lpconfig->file){
|
||||
ms_warning("Could not open %s but %s works, app may have crashed during last sync.",lpconfig->filename,lpconfig->tmpfilename);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (lpconfig->file!=NULL){
|
||||
lp_config_parse(lpconfig,lpconfig->file);
|
||||
fclose(lpconfig->file);
|
||||
#if !defined(WIN32)
|
||||
{
|
||||
struct stat fileStat;
|
||||
if ((stat(config_filename,&fileStat) == 0) && (S_ISREG(fileStat.st_mode))) {
|
||||
/* make existing configuration files non-group/world-accessible */
|
||||
if (chmod(config_filename, S_IRUSR | S_IWUSR) == -1) {
|
||||
ms_warning("unable to correct permissions on "
|
||||
"configuration file: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*WIN32*/
|
||||
|
||||
lpconfig->file=NULL;
|
||||
lpconfig->modified=0;
|
||||
}
|
||||
|
|
@ -396,6 +411,7 @@ void lp_item_set_value(LpItem *item, const char *value){
|
|||
|
||||
static void _lp_config_destroy(LpConfig *lpconfig){
|
||||
if (lpconfig->filename!=NULL) ortp_free(lpconfig->filename);
|
||||
if (lpconfig->tmpfilename) ortp_free(lpconfig->tmpfilename);
|
||||
ms_list_for_each(lpconfig->sections,(void (*)(void*))lp_section_destroy);
|
||||
ms_list_free(lpconfig->sections);
|
||||
free(lpconfig);
|
||||
|
|
@ -583,7 +599,7 @@ int lp_config_sync(LpConfig *lpconfig){
|
|||
/* don't create group/world-accessible files */
|
||||
(void) umask(S_IRWXG | S_IRWXO);
|
||||
#endif
|
||||
file=fopen(lpconfig->filename,"w");
|
||||
file=fopen(lpconfig->tmpfilename,"w");
|
||||
if (file==NULL){
|
||||
ms_warning("Could not write %s ! Maybe it is read-only. Configuration will not be saved.",lpconfig->filename);
|
||||
lpconfig->readonly=1;
|
||||
|
|
@ -591,6 +607,16 @@ int lp_config_sync(LpConfig *lpconfig){
|
|||
}
|
||||
ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file);
|
||||
fclose(file);
|
||||
#ifdef RENAME_REQUIRES_NONEXISTENT_NEW_PATH
|
||||
/* On windows, rename() does not accept that the newpath is an existing file, while it is accepted on Unix.
|
||||
* As a result, we are forced to first delete the linphonerc file, and then rename.*/
|
||||
if (remove(lpconfig->filename)!=0){
|
||||
ms_error("Cannot remove %s: %s",lpconfig->filename, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
if (rename(lpconfig->tmpfilename,lpconfig->filename)!=0){
|
||||
ms_error("Cannot rename %s into %s: %s",lpconfig->tmpfilename,lpconfig->filename,strerror(errno));
|
||||
}
|
||||
lpconfig->modified=0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "linphonecore.h"
|
||||
|
||||
#ifdef MSG_STORAGE_ENABLED
|
||||
#ifndef PRIu64
|
||||
#define PRIu64 "I64u"
|
||||
#endif
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){
|
||||
static ORTP_INLINE LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){
|
||||
MSList* transients = cr->transient_messages;
|
||||
LinphoneChatMessage* chat;
|
||||
while( transients ){
|
||||
|
|
@ -51,18 +54,15 @@ 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);
|
||||
linphone_content_unref(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]);
|
||||
message->file_transfer_information = linphone_content_new();
|
||||
if (argv[1]) linphone_content_set_type(message->file_transfer_information, argv[1]);
|
||||
if (argv[2]) linphone_content_set_subtype(message->file_transfer_information, argv[2]);
|
||||
if (argv[3]) linphone_content_set_name(message->file_transfer_information, argv[3]);
|
||||
if (argv[4]) linphone_content_set_encoding(message->file_transfer_information, argv[4]);
|
||||
linphone_content_set_size(message->file_transfer_information, (size_t)atoi(argv[5]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -196,13 +196,13 @@ static int linphone_chat_message_store_content(LinphoneChatMessage *msg) {
|
|||
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,
|
||||
linphone_content_get_type(content),
|
||||
linphone_content_get_subtype(content),
|
||||
linphone_content_get_name(content),
|
||||
linphone_content_get_encoding(content),
|
||||
linphone_content_get_size(content),
|
||||
NULL
|
||||
);
|
||||
);
|
||||
linphone_sql_request(lc->db, buf);
|
||||
sqlite3_free(buf);
|
||||
id = (unsigned int) sqlite3_last_insert_rowid (lc->db);
|
||||
|
|
@ -225,7 +225,7 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *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);",
|
||||
buf = sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%lld,%Q,%i);",
|
||||
local_contact,
|
||||
peer,
|
||||
msg->dir,
|
||||
|
|
@ -234,10 +234,10 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
|
|||
msg->is_read,
|
||||
msg->state,
|
||||
msg->external_body_url,
|
||||
msg->time,
|
||||
(int64_t)msg->time,
|
||||
msg->appdata,
|
||||
content_id
|
||||
);
|
||||
);
|
||||
linphone_sql_request(lc->db,buf);
|
||||
sqlite3_free(buf);
|
||||
ms_free(local_contact);
|
||||
|
|
@ -250,18 +250,11 @@ 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 (id = %i) AND utc = %i;",
|
||||
msg->state,msg->storage_id,msg->time);
|
||||
char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE (id = %i);",
|
||||
msg->state,msg->storage_id);
|
||||
linphone_sql_request(lc->db,buf);
|
||||
sqlite3_free(buf);
|
||||
}
|
||||
|
||||
if( msg->state == LinphoneChatMessageStateDelivered
|
||||
|| msg->state == LinphoneChatMessageStateNotDelivered ){
|
||||
// message is not transient anymore, we can remove it from our transient list:
|
||||
msg->chat_room->transient_messages = ms_list_remove(msg->chat_room->transient_messages, msg);
|
||||
linphone_chat_message_unref(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_chat_message_store_appdata(LinphoneChatMessage* msg){
|
||||
|
|
@ -361,7 +354,7 @@ void linphone_chat_room_delete_history(LinphoneChatRoom *cr){
|
|||
MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, int endm){
|
||||
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
|
||||
MSList *ret;
|
||||
char *buf;
|
||||
char *buf,*buf2;
|
||||
char *peer;
|
||||
uint64_t begin,end;
|
||||
int buf_max_size = 512;
|
||||
|
|
@ -375,17 +368,24 @@ MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, i
|
|||
buf=ms_malloc(buf_max_size);
|
||||
buf=sqlite3_snprintf(buf_max_size-1,buf,"SELECT * FROM history WHERE remoteContact = %Q ORDER BY id DESC",peer);
|
||||
|
||||
|
||||
if (startm<0) startm=0;
|
||||
|
||||
if (endm>0&&endm>=startm){
|
||||
buf=sqlite3_snprintf(buf_max_size-1,buf,"%s LIMIT %i ",buf,endm+1-startm);
|
||||
if ((endm>0&&endm>=startm) || (startm == 0 && endm == 0) ){
|
||||
buf2=ms_strdup_printf("%s LIMIT %i ",buf,endm+1-startm);
|
||||
ms_free(buf);
|
||||
buf = buf2;
|
||||
}else if(startm>0){
|
||||
ms_message("%s(): end is lower than start (%d < %d). No end assumed.",__FUNCTION__,endm,startm);
|
||||
buf=sqlite3_snprintf(buf_max_size-1,buf,"%s LIMIT -1",buf);
|
||||
ms_message("%s(): end is lower than start (%d < %d). Assuming no end limit.",__FUNCTION__,endm,startm);
|
||||
buf2=ms_strdup_printf("%s LIMIT -1",buf);
|
||||
ms_free(buf);
|
||||
buf = buf2;
|
||||
}
|
||||
|
||||
if (startm>0){
|
||||
buf=sqlite3_snprintf(buf_max_size-1,buf,"%s OFFSET %i ",buf,startm);
|
||||
buf2=ms_strdup_printf("%s OFFSET %i ",buf,startm);
|
||||
ms_free(buf);
|
||||
buf = buf2;
|
||||
}
|
||||
|
||||
begin=ortp_get_cur_time_ms();
|
||||
|
|
@ -400,7 +400,7 @@ MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, i
|
|||
}
|
||||
|
||||
MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){
|
||||
return linphone_chat_room_get_history_range(cr, 0, nb_message);
|
||||
return linphone_chat_room_get_history_range(cr, 0, nb_message-1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -459,7 +459,7 @@ static int migrate_messages_timestamp(void* data,int argc, char** argv, char** c
|
|||
time_t new_time = parse_time_from_db(argv[1]);
|
||||
if( new_time ){
|
||||
/* replace 'time' by -1 and set 'utc' to the timestamp */
|
||||
char *buf = sqlite3_mprintf("UPDATE history SET utc=%i,time='-1' WHERE id=%i;", new_time, atoi(argv[0]));
|
||||
char *buf = sqlite3_mprintf("UPDATE history SET utc=%lld,time='-1' WHERE id=%i;", (int64_t)new_time, atoi(argv[0]));
|
||||
if( buf) {
|
||||
linphone_sql_request((sqlite3*)data, buf);
|
||||
sqlite3_free(buf);
|
||||
|
|
@ -486,7 +486,7 @@ static void linphone_migrate_timestamps(sqlite3* db){
|
|||
uint64_t end;
|
||||
linphone_sql_request(db, "COMMIT");
|
||||
end=ortp_get_cur_time_ms();
|
||||
ms_message("Migrated message timestamps to UTC in %i ms",(int)(end-begin));
|
||||
ms_message("Migrated message timestamps to UTC in %lu ms",(unsigned long)(end-begin));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt,
|
|||
if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt)){
|
||||
payload_type_set_enable(pt,enabled);
|
||||
_linphone_core_codec_config_write(lc);
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
return 0;
|
||||
}
|
||||
ms_error("Enabling codec not in audio or video list of PayloadType !");
|
||||
|
|
@ -113,12 +114,14 @@ void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadTyp
|
|||
if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){
|
||||
pt->normal_bitrate=bitrate*1000;
|
||||
pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE;
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
}else{
|
||||
ms_error("Cannot set an explicit bitrate for codec %s/%i, because it is not VBR.",pt->mime_type,pt->clock_rate);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ms_error("linphone_core_set_payload_type_bitrate() payload type not in audio or video list !");
|
||||
}
|
||||
ms_error("linphone_core_set_payload_type_bitrate() payload type not in audio or video list !");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -188,7 +191,6 @@ int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const LinphonePaylo
|
|||
return get_audio_payload_bandwidth(lc,pt,maxbw);
|
||||
}else if (pt->type==PAYLOAD_VIDEO){
|
||||
int video_bw;
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
if (maxbw<=0) {
|
||||
video_bw=1500; /*default bitrate for video stream when no bandwidth limit is set, around 1.5 Mbit/s*/
|
||||
}else{
|
||||
|
|
@ -250,7 +252,19 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, cons
|
|||
|
||||
/* return TRUE if codec can be used with bandwidth, FALSE else*/
|
||||
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt){
|
||||
return linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, linphone_core_get_payload_type_bitrate(lc,pt));
|
||||
bool_t ret=linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, linphone_core_get_payload_type_bitrate(lc,pt));
|
||||
if ((pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED)
|
||||
&& lc->sound_conf.capt_sndcard
|
||||
&& !(ms_snd_card_get_capabilities(lc->sound_conf.capt_sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER)
|
||||
&& linphone_core_echo_cancellation_enabled(lc)
|
||||
&& (pt->clock_rate!=16000 && pt->clock_rate!=8000)
|
||||
&& strcasecmp(pt->mime_type,"opus")!=0
|
||||
&& ms_filter_lookup_by_name("MSWebRTCAEC")!=NULL){
|
||||
ms_warning("Payload type %s/%i cannot be used because software echo cancellation is required but is unable to operate at this rate.",
|
||||
pt->mime_type,pt->clock_rate);
|
||||
ret=FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){
|
||||
|
|
@ -627,6 +641,24 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const char *linphone_ice_state_to_string(LinphoneIceState state){
|
||||
switch(state){
|
||||
case LinphoneIceStateFailed:
|
||||
return "IceStateFailed";
|
||||
case LinphoneIceStateHostConnection:
|
||||
return "IceStateHostConnection";
|
||||
case LinphoneIceStateInProgress:
|
||||
return "IceStateInProgress";
|
||||
case LinphoneIceStateNotActivated:
|
||||
return "IceStateNotActivated";
|
||||
case LinphoneIceStateReflexiveConnection:
|
||||
return "IceStateReflexiveConnection";
|
||||
case LinphoneIceStateRelayConnection:
|
||||
return "IceStateRelayConnection";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
|
||||
{
|
||||
IceCheckList *audio_check_list;
|
||||
|
|
@ -673,7 +705,7 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
|
|||
} else {
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed;
|
||||
}
|
||||
}
|
||||
}else call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated;
|
||||
} else if (session_state == IS_Running) {
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
|
||||
if (call->params->has_video && (video_check_list != NULL)) {
|
||||
|
|
@ -685,9 +717,11 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
|
|||
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed;
|
||||
}
|
||||
}
|
||||
ms_message("Call [%p] New ICE state: audio: [%s] video: [%s]", call,
|
||||
linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state));
|
||||
}
|
||||
|
||||
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
|
||||
void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
|
||||
{
|
||||
const char *rtp_addr, *rtcp_addr;
|
||||
IceSessionState session_state = ice_session_state(session);
|
||||
|
|
@ -808,7 +842,7 @@ static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed){
|
|||
call->videostream->ms.ice_check_list=NULL;
|
||||
}
|
||||
|
||||
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md)
|
||||
void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md)
|
||||
{
|
||||
bool_t ice_restarted = FALSE;
|
||||
|
||||
|
|
@ -966,6 +1000,8 @@ unsigned int linphone_core_get_audio_features(LinphoneCore *lc){
|
|||
else if (strcasecmp(name,"DTMF")==0) ret|=AUDIO_STREAM_FEATURE_DTMF;
|
||||
else if (strcasecmp(name,"DTMF_ECHO")==0) ret|=AUDIO_STREAM_FEATURE_DTMF_ECHO;
|
||||
else if (strcasecmp(name,"MIXED_RECORDING")==0) ret|=AUDIO_STREAM_FEATURE_MIXED_RECORDING;
|
||||
else if (strcasecmp(name,"LOCAL_PLAYING")==0) ret|=AUDIO_STREAM_FEATURE_LOCAL_PLAYING;
|
||||
else if (strcasecmp(name,"REMOTE_PLAYING")==0) ret|=AUDIO_STREAM_FEATURE_REMOTE_PLAYING;
|
||||
else if (strcasecmp(name,"ALL")==0) ret|=AUDIO_STREAM_FEATURE_ALL;
|
||||
else if (strcasecmp(name,"NONE")==0) ret=0;
|
||||
else ms_error("Unsupported audio feature %s requested in config file.",name);
|
||||
|
|
|
|||
|
|
@ -97,6 +97,18 @@ void linphone_player_close(LinphonePlayer *obj){
|
|||
return obj->close(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy a player
|
||||
* @param obj The player
|
||||
*/
|
||||
void linphone_player_destroy(LinphonePlayer *obj) {
|
||||
if(obj->destroy) obj->destroy(obj);
|
||||
}
|
||||
|
||||
void _linphone_player_destroy(LinphonePlayer *player) {
|
||||
ms_free(player);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call player implementation below.
|
||||
|
|
@ -169,7 +181,7 @@ static void call_player_close(LinphonePlayer *player){
|
|||
}
|
||||
|
||||
static void on_call_destroy(void *obj, belle_sip_object_t *call_being_destroyed){
|
||||
ms_free(obj);
|
||||
_linphone_player_destroy(obj);
|
||||
}
|
||||
|
||||
LinphonePlayer *linphone_call_build_player(LinphoneCall *call){
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ 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*/
|
||||
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;
|
||||
};
|
||||
|
|
@ -125,12 +125,13 @@ struct _LinphoneCallLog{
|
|||
LinphoneAddress *from; /**<Originator of the call as a LinphoneAddress object*/
|
||||
LinphoneAddress *to; /**<Destination of the call as a LinphoneAddress object*/
|
||||
char start_date[128]; /**<Human readable string containing the start date*/
|
||||
int duration; /**<Duration of the call in seconds*/
|
||||
int duration; /**<Duration of the call starting in connected state in seconds*/
|
||||
char *refkey;
|
||||
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 */
|
||||
time_t connected_date_time; /**Connecting 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;
|
||||
|
|
@ -145,6 +146,17 @@ typedef struct _CallCallbackObj
|
|||
void * _user_data;
|
||||
}CallCallbackObj;
|
||||
|
||||
struct _LinphoneChatMessageCbs {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
LinphoneChatMessageMsgStateChangedCb msg_state_changed;
|
||||
LinphoneChatMessageFileTransferRecvCb file_transfer_recv; /**< Callback to store file received attached to a #LinphoneChatMessage */
|
||||
LinphoneChatMessageFileTransferSendCb file_transfer_send; /**< Callback to collect file chunk to be sent for a #LinphoneChatMessage */
|
||||
LinphoneChatMessageFileTransferProgressIndicationCb file_transfer_progress_indication; /**< Callback to indicate file transfer progress */
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneChatMessageCbs);
|
||||
|
||||
typedef enum _LinphoneChatMessageDir{
|
||||
LinphoneChatMessageIncoming,
|
||||
LinphoneChatMessageOutgoing
|
||||
|
|
@ -153,6 +165,7 @@ typedef enum _LinphoneChatMessageDir{
|
|||
struct _LinphoneChatMessage {
|
||||
belle_sip_object_t base;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneChatMessageCbs *callbacks;
|
||||
LinphoneChatMessageDir dir;
|
||||
char* message;
|
||||
LinphoneChatMessageStateChangedCb cb;
|
||||
|
|
@ -171,6 +184,7 @@ struct _LinphoneChatMessage {
|
|||
LinphoneContent *file_transfer_information; /**< used to store file transfer information when the message is of file transfer type */
|
||||
char *content_type; /**< is used to specified the type of message to be sent, used only for file transfer message */
|
||||
belle_http_request_t *http_request; /**< keep a reference to the http_request in case of file transfer in order to be able to cancel the transfer */
|
||||
char *file_transfer_filepath;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneChatMessage);
|
||||
|
|
@ -186,8 +200,7 @@ typedef struct _PortConfig{
|
|||
int rtcp_port;
|
||||
}PortConfig;
|
||||
|
||||
struct _LinphoneCall
|
||||
{
|
||||
struct _LinphoneCall{
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
struct _LinphoneCore *core;
|
||||
|
|
@ -203,7 +216,6 @@ struct _LinphoneCall
|
|||
SalOp *op;
|
||||
SalOp *ping_op;
|
||||
char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */
|
||||
time_t media_start_time; /*time at which it was accepted, media streams established*/
|
||||
LinphoneCallState state;
|
||||
LinphoneCallState prevstate;
|
||||
LinphoneCallState transfer_state; /*idle if no transfer*/
|
||||
|
|
@ -238,6 +250,9 @@ struct _LinphoneCall
|
|||
int localdesc_changed;/*not a boolean, contains a mask representing changes*/
|
||||
LinphonePlayer *player;
|
||||
|
||||
char *dtmf_sequence; /*DTMF sequence needed to be sent using #dtmfs_timer*/
|
||||
belle_sip_source_t *dtmfs_timer; /*DTMF timer needed to send a DTMF sequence*/
|
||||
|
||||
bool_t refer_pending;
|
||||
bool_t expect_media_in_ack;
|
||||
bool_t audio_muted;
|
||||
|
|
@ -373,8 +388,9 @@ void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, Linphone
|
|||
int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call);
|
||||
void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call);
|
||||
void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEvent *ev);
|
||||
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);
|
||||
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
|
||||
void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);
|
||||
void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall *call);
|
||||
void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
|
||||
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md);
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
|
||||
|
|
@ -409,8 +425,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);
|
||||
|
||||
int _linphone_core_apply_transports(LinphoneCore *lc);
|
||||
const char * linphone_core_get_identity(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose);
|
||||
|
|
@ -438,6 +453,7 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
|
|||
/*chat*/
|
||||
void linphone_chat_room_release(LinphoneChatRoom *cr);
|
||||
void linphone_chat_message_destroy(LinphoneChatMessage* msg);
|
||||
void linphone_chat_message_update_state(LinphoneChatMessage* chat_msg );
|
||||
/**/
|
||||
|
||||
struct _LinphoneProxyConfig
|
||||
|
|
@ -463,17 +479,17 @@ struct _LinphoneProxyConfig
|
|||
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;
|
||||
uint8_t avpf_rr_interval;
|
||||
uint8_t quality_reporting_interval;
|
||||
|
||||
|
||||
time_t deletion_date;
|
||||
LinphonePrivacyMask privacy;
|
||||
/*use to check if server config has changed between edit() and done()*/
|
||||
|
|
@ -768,6 +784,7 @@ struct _LinphoneCore
|
|||
LinphoneReason chat_deny_code;
|
||||
const char **supported_formats;
|
||||
LinphoneContent *log_collection_upload_information;
|
||||
LinphoneCoreVTable *current_vtable; // the latest vtable to call a callback, see linphone_core_get_current_vtable
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -884,10 +901,9 @@ void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *d
|
|||
void linphone_call_create_op(LinphoneCall *call);
|
||||
int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer);
|
||||
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody *body);
|
||||
void linphone_content_uninit(LinphoneContent * obj);
|
||||
void linphone_content_copy(LinphoneContent *obj, const LinphoneContent *ref);
|
||||
LinphoneContent *linphone_content_copy_from_sal_body(LinphoneContent *obj, const SalBody *ref);
|
||||
SalBody *sal_body_from_content(SalBody *body, const LinphoneContent *lc);
|
||||
LinphoneContent * linphone_content_new(void);
|
||||
LinphoneContent * linphone_content_copy(const LinphoneContent *ref);
|
||||
SalBody *sal_body_from_content(SalBody *body, const LinphoneContent *content);
|
||||
SalReason linphone_reason_to_sal(LinphoneReason reason);
|
||||
LinphoneReason linphone_reason_from_sal(SalReason reason);
|
||||
LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires);
|
||||
|
|
@ -899,9 +915,21 @@ LinphoneEvent *linphone_event_new_with_out_of_dialog_op(LinphoneCore *lc, SalOp
|
|||
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state);
|
||||
void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state);
|
||||
LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss);
|
||||
const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref);
|
||||
LinphoneContent *linphone_content_from_sal_body(const SalBody *ref);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
|
||||
|
||||
|
||||
struct _LinphoneContent {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
struct _LinphoneContentPrivate lcp;
|
||||
bool_t owned_fields;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneContent);
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* REMOTE PROVISIONING FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
|
@ -923,11 +951,14 @@ struct _LinphonePlayer{
|
|||
int (*get_duration)(struct _LinphonePlayer *player);
|
||||
int (*get_position)(struct _LinphonePlayer *player);
|
||||
void (*close)(struct _LinphonePlayer* player);
|
||||
void (*destroy)(struct _LinphonePlayer *player);
|
||||
LinphonePlayerEofCallback cb;
|
||||
void *user_data;
|
||||
void *impl;
|
||||
};
|
||||
|
||||
void _linphone_player_destroy(LinphonePlayer *player);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* XML UTILITY FUNCTIONS *
|
||||
|
|
@ -979,7 +1010,9 @@ BELLE_SIP_TYPE_ID(LinphoneCall),
|
|||
BELLE_SIP_TYPE_ID(LinphoneCallLog),
|
||||
BELLE_SIP_TYPE_ID(LinphoneCallParams),
|
||||
BELLE_SIP_TYPE_ID(LinphoneChatMessage),
|
||||
BELLE_SIP_TYPE_ID(LinphoneChatMessageCbs),
|
||||
BELLE_SIP_TYPE_ID(LinphoneChatRoom),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContent),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch),
|
||||
BELLE_SIP_TYPE_ID(LinphoneProxyConfig)
|
||||
|
|
@ -1004,7 +1037,7 @@ void linphone_core_notify_text_message_received(LinphoneCore *lc, LinphoneChatRo
|
|||
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_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total);
|
||||
void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room);
|
||||
void linphone_core_notify_dtmf_received(LinphoneCore* lc, LinphoneCall *call, int dtmf);
|
||||
/*
|
||||
|
|
@ -1022,7 +1055,7 @@ void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev,
|
|||
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 linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t offset, size_t total);
|
||||
|
||||
void set_mic_gain_db(AudioStream *st, float gain);
|
||||
void set_playback_gain_db(AudioStream *st, float gain);
|
||||
|
|
|
|||
|
|
@ -881,8 +881,11 @@ static bool_t is_a_phone_number(const char *username){
|
|||
*p==')' ||
|
||||
*p=='(' ||
|
||||
*p=='/' ||
|
||||
*p=='+') continue;
|
||||
else return FALSE;
|
||||
*p=='+' ||
|
||||
(unsigned char)*p== 0xca // non-breakable space (iOS uses it to format contacts phone number)
|
||||
)
|
||||
continue;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -921,7 +924,7 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
if (is_a_phone_number(username)){
|
||||
char *flatten;
|
||||
flatten=flatten_number(username);
|
||||
ms_message("Flattened number is '%s'",flatten);
|
||||
ms_debug("Flattened number is '%s'",flatten);
|
||||
|
||||
if (proxy->dial_prefix==NULL || proxy->dial_prefix[0]=='\0'){
|
||||
/*no prefix configured, nothing else to do*/
|
||||
|
|
@ -931,10 +934,10 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
}else{
|
||||
dial_plan_t dialplan;
|
||||
lookup_dial_plan(proxy->dial_prefix,&dialplan);
|
||||
ms_message("Using dialplan '%s'",dialplan.country);
|
||||
ms_debug("Using dialplan '%s'",dialplan.country);
|
||||
if (flatten[0]=='+' || strstr(flatten,dialplan.icp)==flatten){
|
||||
/* the number has international prefix or +, so nothing to do*/
|
||||
ms_message("Prefix already present.");
|
||||
ms_debug("Prefix already present.");
|
||||
/*eventually replace the plus*/
|
||||
replace_plus(flatten,result,result_len,proxy->dial_escape_plus ? dialplan.icp : NULL);
|
||||
ms_free(flatten);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
|
@ -257,7 +257,7 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off
|
|||
}
|
||||
|
||||
static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) {
|
||||
LinphoneContent content = {0};
|
||||
LinphoneContent *content = linphone_content_new();
|
||||
LinphoneAddress *addr;
|
||||
int expires = -1;
|
||||
size_t offset = 0;
|
||||
|
|
@ -294,9 +294,9 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
|
|||
goto end;
|
||||
}
|
||||
|
||||
buffer = (char *) ms_malloc(size);
|
||||
content.type = ms_strdup("application");
|
||||
content.subtype = ms_strdup("vq-rtcpxr");
|
||||
buffer = (char *) belle_sip_malloc(size);
|
||||
linphone_content_set_type(content, "application");
|
||||
linphone_content_set_subtype(content, "vq-rtcpxr");
|
||||
|
||||
append_to_buffer(&buffer, &size, &offset, "%s\r\n", report_event);
|
||||
append_to_buffer(&buffer, &size, &offset, "CallID: %s\r\n", report->info.call_id);
|
||||
|
|
@ -331,17 +331,16 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
|
|||
append_to_buffer(&buffer, &size, &offset, "\r\n");
|
||||
}
|
||||
|
||||
content.data = buffer;
|
||||
content.size = strlen(buffer);
|
||||
linphone_content_set_buffer(content, buffer, strlen(buffer));
|
||||
|
||||
if (call->log->reporting.on_report_sent != NULL){
|
||||
call->log->reporting.on_report_sent(
|
||||
call,
|
||||
(report==call->log->reporting.reports[0])?LINPHONE_CALL_STATS_AUDIO:LINPHONE_CALL_STATS_VIDEO,
|
||||
&content);
|
||||
content);
|
||||
}
|
||||
|
||||
if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, &content)){
|
||||
if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, content)){
|
||||
ret=4;
|
||||
} else {
|
||||
reset_avg_metrics(report);
|
||||
|
|
@ -354,7 +353,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
|
|||
|
||||
linphone_address_destroy(addr);
|
||||
|
||||
linphone_content_uninit(&content);
|
||||
linphone_content_unref(content);
|
||||
|
||||
end:
|
||||
ms_message("QualityReporting[%p]: Send '%s' with status %d",
|
||||
|
|
@ -386,7 +385,7 @@ static void update_ip(LinphoneCall * call, int stats_type) {
|
|||
if (local_desc != NULL) {
|
||||
/*since this function might be called for video stream AFTER it has been uninitialized, local description might
|
||||
be invalid. In any other case, IP/port should be always filled and valid*/
|
||||
if (local_desc->rtp_addr != NULL && strlen(local_desc->rtp_addr) > 0) {
|
||||
if (strlen(local_desc->rtp_addr) > 0) {
|
||||
call->log->reporting.reports[stats_type]->info.local_addr.port = local_desc->rtp_port;
|
||||
STR_REASSIGN(call->log->reporting.reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr));
|
||||
}
|
||||
|
|
@ -397,7 +396,7 @@ static void update_ip(LinphoneCall * call, int stats_type) {
|
|||
call->log->reporting.reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port;
|
||||
|
||||
/*for IP it can be not set if we are using a direct route*/
|
||||
if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) {
|
||||
if (strlen(remote_desc->rtp_addr) > 0) {
|
||||
STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr));
|
||||
} else {
|
||||
STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr));
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ char * linphone_upnp_format_device_id(const char *device_id) {
|
|||
if(device_id == NULL) {
|
||||
return ret;
|
||||
}
|
||||
ret = ms_new(char, UPNP_UUID_LEN + 1);
|
||||
ret = ms_new0(char, UPNP_UUID_LEN + 1);
|
||||
tmp = ret;
|
||||
if(linphone_upnp_strncmpi(device_id, "uuid:", linphone_upnp_str_min(device_id, "uuid:")) == 0) {
|
||||
device_id += strlen("uuid:");
|
||||
|
|
@ -840,6 +840,8 @@ int linphone_upnp_call_process(LinphoneCall *call) {
|
|||
linphone_core_proceed_with_invite_if_ready(lc, call, NULL);
|
||||
break;
|
||||
case LinphoneCallIdle:
|
||||
linphone_call_update_local_media_description_from_ice_or_upnp(call);
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
linphone_core_notify_incoming_call(lc, call);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
87
gtk/CMakeLists.txt
Normal file
87
gtk/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
############################################################################
|
||||
# CMakeLists.txt
|
||||
# Copyright (C) 2014 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
find_package(GTK2 2.18 REQUIRED gtk)
|
||||
|
||||
set(UI_FILES
|
||||
about.ui
|
||||
audio_assistant.ui
|
||||
buddylookup.ui
|
||||
call_logs.ui
|
||||
call_statistics.ui
|
||||
config-uri.ui
|
||||
contact.ui
|
||||
dscp_settings.ui
|
||||
keypad.ui
|
||||
ldap.ui
|
||||
log.ui
|
||||
main.ui
|
||||
parameters.ui
|
||||
password.ui
|
||||
provisioning-fetch.ui
|
||||
sip_account.ui
|
||||
tunnel_config.ui
|
||||
waiting.ui
|
||||
)
|
||||
|
||||
set(PIXMAPS stock_people.png)
|
||||
|
||||
set(SOURCE_FILES
|
||||
audio_assistant.c
|
||||
buddylookup.c
|
||||
calllogs.c
|
||||
chat.c
|
||||
conference.c
|
||||
config-fetching.c
|
||||
friendlist.c
|
||||
incall_view.c
|
||||
logging.c
|
||||
loginframe.c
|
||||
main.c
|
||||
propertybox.c
|
||||
singleinstance.c
|
||||
support.c
|
||||
update.c
|
||||
utils.c
|
||||
videowindow.c
|
||||
)
|
||||
|
||||
add_executable(linphone-gtk ${SOURCE_FILES})
|
||||
set_target_properties(linphone-gtk PROPERTIES OUTPUT_NAME linphone)
|
||||
target_include_directories(linphone-gtk PUBLIC ${GTK2_INCLUDE_DIRS})
|
||||
target_link_libraries(linphone-gtk linphone ${GTK2_LIBRARIES})
|
||||
if(ENABLE_NOTIFY)
|
||||
target_include_directories(linphone-gtk PUBLIC ${NOTIFY_INCLUDE_DIRS})
|
||||
target_link_libraries(linphone-gtk ${NOTIFY_LIBRARIES})
|
||||
endif()
|
||||
|
||||
install(TARGETS linphone-gtk
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
)
|
||||
|
||||
install(FILES ${UI_FILES} ${PIXMAPS}
|
||||
DESTINATION ${PACKAGE_DATA_DIR}/linphone
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
|
|
@ -5,14 +5,14 @@
|
|||
<object class="GtkAboutDialog" id="about">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">About linphone</property>
|
||||
<property name="title" translatable="yes">About Linphone</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<property name="program_name">Linphone</property>
|
||||
<property name="version">undef</property>
|
||||
<property name="copyright" translatable="yes">(C) Belledonne Communications,2010
|
||||
<property name="copyright" translatable="yes">(C) Belledonne Communications, 2010
|
||||
</property>
|
||||
<property name="comments" translatable="yes">An internet video phone using the standard SIP (rfc3261) protocol.</property>
|
||||
<property name="website">http://www.linphone.org</property>
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ static void open_mixer(){
|
|||
|
||||
static GtkWidget *create_intro(){
|
||||
GtkWidget *vbox=gtk_vbox_new(FALSE,2);
|
||||
GtkWidget *label=gtk_label_new(_("Welcome !\nThis assistant will help you to configure audio settings for Linphone"));
|
||||
GtkWidget *label=gtk_label_new(_("Welcome!\nThis assistant will help you to configure audio settings for Linphone"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2);
|
||||
gtk_widget_show_all(vbox);
|
||||
return vbox;
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ void linphone_gtk_call_log_update(GtkWidget *w){
|
|||
ngettext("%i second", "%i seconds", duration%60),
|
||||
duration%60);
|
||||
if (status==NULL) {
|
||||
headtxt=g_markup_printf_escaped(_("<big><b>%s</b></big>\t%s"),display,start_date ? start_date : "");
|
||||
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"
|
||||
"<i>Quality: %s</i></small>\n%s\t%s\t"),
|
||||
|
|
@ -340,8 +340,8 @@ void linphone_gtk_call_log_update(GtkWidget *w){
|
|||
} else {
|
||||
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></small>\t"
|
||||
"\n%s"),addr, status);
|
||||
"<small><i>%s</i></small>\t"
|
||||
"\n%s",addr, status);
|
||||
}
|
||||
g_free(minutes);
|
||||
g_free(seconds);
|
||||
|
|
|
|||
10
gtk/chat.c
10
gtk/chat.c
|
|
@ -276,7 +276,7 @@ void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessag
|
|||
}
|
||||
}
|
||||
|
||||
static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *user_pointer){
|
||||
static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state){
|
||||
update_chat_state_message(state,msg);
|
||||
}
|
||||
|
||||
|
|
@ -300,8 +300,11 @@ void linphone_gtk_send_text(){
|
|||
entered=gtk_entry_get_text(GTK_ENTRY(entry));
|
||||
if (strlen(entered)>0) {
|
||||
LinphoneChatMessage *msg;
|
||||
LinphoneChatMessageCbs *cbs;
|
||||
msg=linphone_chat_room_create_message(cr,entered);
|
||||
linphone_chat_room_send_message2(cr,msg,on_chat_state_changed,NULL);
|
||||
cbs=linphone_chat_message_get_callbacks(msg);
|
||||
linphone_chat_message_cbs_set_msg_state_changed(cbs,on_chat_state_changed);
|
||||
linphone_chat_room_send_chat_message(cr,msg);
|
||||
linphone_gtk_push_text(w,linphone_chat_message_get_from(msg),
|
||||
TRUE,cr,msg,FALSE);
|
||||
|
||||
|
|
@ -471,8 +474,9 @@ void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,
|
|||
}
|
||||
|
||||
void linphone_gtk_chat_destroyed(GtkWidget *w){
|
||||
/*
|
||||
LinphoneChatRoom *cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(w),"cr");
|
||||
linphone_chat_room_destroy(cr);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ Please enter or modify the configuration URI below. After clicking OK, Linphone
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="text" translatable="yes">https://</property>
|
||||
<property name="text" translatable="no">https://</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">True</property>
|
||||
|
|
|
|||
|
|
@ -426,7 +426,9 @@ void linphone_gtk_update_video_button(LinphoneCall *call){
|
|||
GtkWidget *conf_frame;
|
||||
const LinphoneCallParams *params=linphone_call_get_current_params(call);
|
||||
gboolean has_video=linphone_call_params_video_enabled(params);
|
||||
gboolean button_sensitive=FALSE;
|
||||
if (call_view==NULL) return;
|
||||
|
||||
button=linphone_gtk_get_widget(call_view,"video_button");
|
||||
|
||||
gtk_button_set_image(GTK_BUTTON(button),
|
||||
|
|
@ -436,12 +438,20 @@ void linphone_gtk_update_video_button(LinphoneCall *call){
|
|||
gtk_widget_set_sensitive(button,FALSE);
|
||||
return;
|
||||
}
|
||||
switch(linphone_call_get_state(call)){
|
||||
case LinphoneCallStreamsRunning:
|
||||
button_sensitive=!linphone_call_media_in_progress(call);
|
||||
break;
|
||||
default:
|
||||
button_sensitive=FALSE;
|
||||
break;
|
||||
}
|
||||
gtk_widget_set_sensitive(button,button_sensitive);
|
||||
if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"signal_connected"))==0){
|
||||
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));
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
@ -705,7 +715,7 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *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"));
|
||||
|
|
@ -758,7 +768,7 @@ void linphone_gtk_in_call_view_update_duration(LinphoneCall *call){
|
|||
int seconds=duration%60;
|
||||
int minutes=(duration/60)%60;
|
||||
int hours=duration/3600;
|
||||
snprintf(tmp,sizeof(tmp)-1,_("%02i::%02i::%02i"),hours,minutes,seconds);
|
||||
snprintf(tmp,sizeof(tmp)-1,"%02i::%02i::%02i",hours,minutes,seconds);
|
||||
gtk_label_set_text(GTK_LABEL(duration_label),tmp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_D">
|
||||
<property name="label" translatable="yes">D</property>
|
||||
<property name="label" translatable="no">D</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_#">
|
||||
<property name="label" translatable="yes">#</property>
|
||||
<property name="label" translatable="no">#</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_0">
|
||||
<property name="label" translatable="yes">0</property>
|
||||
<property name="label" translatable="no">0</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_*">
|
||||
<property name="label" translatable="yes">*</property>
|
||||
<property name="label" translatable="no">*</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_C">
|
||||
<property name="label" translatable="yes">C</property>
|
||||
<property name="label" translatable="no">C</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_9">
|
||||
<property name="label" translatable="yes">9</property>
|
||||
<property name="label" translatable="no">9</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -123,7 +123,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_8">
|
||||
<property name="label" translatable="yes">8</property>
|
||||
<property name="label" translatable="no">8</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -139,7 +139,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_7">
|
||||
<property name="label" translatable="yes">7</property>
|
||||
<property name="label" translatable="no">7</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -153,7 +153,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_B">
|
||||
<property name="label" translatable="yes">B</property>
|
||||
<property name="label" translatable="no">B</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -169,7 +169,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_6">
|
||||
<property name="label" translatable="yes">6</property>
|
||||
<property name="label" translatable="no">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -185,7 +185,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_5">
|
||||
<property name="label" translatable="yes">5</property>
|
||||
<property name="label" translatable="no">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_4">
|
||||
<property name="label" translatable="yes">4</property>
|
||||
<property name="label" translatable="no">4</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -215,7 +215,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_A">
|
||||
<property name="label" translatable="yes">A</property>
|
||||
<property name="label" translatable="no">A</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -229,7 +229,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_3">
|
||||
<property name="label" translatable="yes">3</property>
|
||||
<property name="label" translatable="no">3</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -243,7 +243,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_2">
|
||||
<property name="label" translatable="yes">2</property>
|
||||
<property name="label" translatable="no">2</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
|
|
@ -257,7 +257,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dtmf_1">
|
||||
<property name="label" translatable="yes">1</property>
|
||||
<property name="label" translatable="no">1</property>
|
||||
<property name="width_request">40</property>
|
||||
<property name="height_request">40</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
|
|||
11
gtk/main.c
11
gtk/main.c
|
|
@ -1228,14 +1228,19 @@ static bool_t notify_actions_supported() {
|
|||
}
|
||||
|
||||
static NotifyNotification* build_notification(const char *title, const char *body) {
|
||||
const char *icon_path = linphone_gtk_get_ui_config("icon", LINPHONE_ICON);
|
||||
GdkPixbuf *pbuf = create_pixbuf(icon_path);
|
||||
NotifyNotification *n = notify_notification_new(title, body, NULL
|
||||
#ifdef HAVE_NOTIFY1
|
||||
,NULL
|
||||
#endif
|
||||
);
|
||||
notify_notification_set_icon_from_pixbuf(n, pbuf);
|
||||
#ifndef HAVE_NOTIFY1
|
||||
{
|
||||
const char *icon_path = linphone_gtk_get_ui_config("icon", LINPHONE_ICON);
|
||||
GdkPixbuf *pbuf = create_pixbuf(icon_path);
|
||||
/*with notify1, this function makes the notification crash the app with obscure dbus glib critical errors*/
|
||||
notify_notification_set_icon_from_pixbuf(n, pbuf);
|
||||
}
|
||||
#endif
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1890,7 +1890,7 @@
|
|||
<object class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Welcome !</b></property>
|
||||
<property name="label" translatable="yes"><b>Welcome!</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Welcome !
|
||||
This wizard will help you to setup a SIP account.
|
||||
<property name="label" translatable="yes">Welcome!
|
||||
This wizard will help you to setup a SIP account.
|
||||
</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
|
|
|
|||
|
|
@ -2538,7 +2538,7 @@
|
|||
<object class="GtkLabel" id="ldap_server">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="label" translatable="no">label</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
@ -2550,7 +2550,7 @@
|
|||
<object class="GtkLabel" id="ldap_auth_method">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="label" translatable="no">label</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
@ -2564,7 +2564,7 @@
|
|||
<object class="GtkLabel" id="ldap_username">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="label" translatable="no">label</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ static GdkPixbuf *notok;
|
|||
|
||||
static GtkWidget *create_intro(){
|
||||
GtkWidget *vbox=gtk_vbox_new(FALSE,2);
|
||||
GtkWidget *label=gtk_label_new(_("Welcome !\nThis assistant will help you to use a SIP account for your calls."));
|
||||
GtkWidget *label=gtk_label_new(_("Welcome!\nThis assistant will help you to use a SIP account for your calls."));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2);
|
||||
g_object_set_data(G_OBJECT(vbox),"label",label);
|
||||
gtk_widget_show_all(vbox);
|
||||
|
|
@ -452,7 +452,7 @@ static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page
|
|||
linphone_core_add_auth_info(linphone_gtk_get_core(),info);
|
||||
linphone_address_destroy(identity);
|
||||
|
||||
if (strcmp(creator->domain, "sip:sip.linphone.org") == 0 ){
|
||||
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)) {
|
||||
|
|
@ -465,6 +465,8 @@ static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page
|
|||
ms_free(tmp);
|
||||
linphone_address_destroy(addr);
|
||||
}
|
||||
linphone_core_set_stun_server(linphone_gtk_get_core(), "stun.linphone.org");
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(), LinphonePolicyUseIce);
|
||||
}
|
||||
|
||||
if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "linphone.h"
|
||||
|
||||
#ifdef __linux
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <gdk/gdkx.h>
|
||||
#elif defined(WIN32)
|
||||
#include <gdk/gdkwin32.h>
|
||||
|
|
@ -74,7 +74,7 @@ static void drag_data_received(GtkWidget *widget, GdkDragContext *context, gint
|
|||
}
|
||||
|
||||
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)
|
||||
#if GTK_CHECK_VERSION(2,21,0)
|
||||
GList *l=gdk_drag_context_list_targets(drag_context);
|
||||
GList *elem;
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ static gboolean drag_drop(GtkWidget *widget, GdkDragContext *drag_context, gint
|
|||
}
|
||||
|
||||
unsigned long get_native_handle(GdkWindow *gdkw){
|
||||
#ifdef __linux
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
return (unsigned long)GDK_WINDOW_XID(gdkw);
|
||||
#elif defined(WIN32)
|
||||
return (unsigned long)GDK_WINDOW_HWND(gdkw);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ typedef enum {
|
|||
SalTransportUDP, /*UDP*/
|
||||
SalTransportTCP, /*TCP*/
|
||||
SalTransportTLS, /*TLS*/
|
||||
SalTransportDTLS /*DTLS*/
|
||||
SalTransportDTLS, /*DTLS*/
|
||||
}SalTransport;
|
||||
|
||||
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
|
||||
|
|
@ -110,6 +110,9 @@ void sal_address_set_transport_name(SalAddress* addr,const char* transport);
|
|||
void sal_address_set_params(SalAddress *addr, const char *params);
|
||||
void sal_address_set_uri_params(SalAddress *addr, const char *params);
|
||||
bool_t sal_address_is_ipv6(SalAddress *addr);
|
||||
void sal_address_set_password(SalAddress *addr, const char *passwd);
|
||||
const char *sal_address_get_password(const SalAddress *addr);
|
||||
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value);
|
||||
|
||||
Sal * sal_init();
|
||||
void sal_uninit(Sal* sal);
|
||||
|
|
@ -516,7 +519,7 @@ void sal_signing_key_delete(SalSigningKey *key);
|
|||
|
||||
|
||||
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
|
||||
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure);
|
||||
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_tunneled);
|
||||
int sal_get_listening_port(Sal *ctx, SalTransport tr);
|
||||
int sal_unlisten_ports(Sal *ctx);
|
||||
int sal_transport_available(Sal *ctx, SalTransport t);
|
||||
|
|
@ -533,8 +536,7 @@ void sal_append_stack_string_to_user_agent(Sal *ctx);
|
|||
/*keepalive period in ms*/
|
||||
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
|
||||
void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled);
|
||||
int sal_enable_tunnel(Sal *ctx, void *tunnelclient);
|
||||
void sal_disable_tunnel(Sal *ctx);
|
||||
int sal_set_tunnel(Sal *ctx, void *tunnelclient);
|
||||
/*Default value is true*/
|
||||
void sal_enable_sip_update_method(Sal *ctx,bool_t value);
|
||||
|
||||
|
|
@ -639,6 +641,12 @@ bool_t sal_call_autoanswer_asked(SalOp *op);
|
|||
void sal_call_send_vfu_request(SalOp *h);
|
||||
int sal_call_is_offerer(const SalOp *h);
|
||||
int sal_call_notify_refer_state(SalOp *h, SalOp *newcall);
|
||||
/* Call test API */
|
||||
/*willingly fails to parse SDP from received packets (INVITE and/or ACK) if value=true */
|
||||
/* First version: for all new SalOp created (eg. each incoming or outgoing call). Do not forget to reset previous value when you are done!*/
|
||||
void sal_default_enable_sdp_removal(Sal* h, bool_t enable) ;
|
||||
/* Second version: for a specific call*/
|
||||
void sal_call_enable_sdp_removal(SalOp *h, bool_t enable) ;
|
||||
|
||||
/*Registration*/
|
||||
int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
|
||||
|
|
@ -750,6 +758,7 @@ LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
|
|||
LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file);
|
||||
LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal);
|
||||
unsigned int sal_get_random(void);
|
||||
char *sal_get_random_token(int size);
|
||||
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
|
||||
belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name);
|
||||
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer);
|
||||
|
|
|
|||
BIN
java/common/org/.DS_Store
vendored
BIN
java/common/org/.DS_Store
vendored
Binary file not shown.
BIN
java/common/org/linphone/.DS_Store
vendored
BIN
java/common/org/linphone/.DS_Store
vendored
Binary file not shown.
|
|
@ -119,6 +119,15 @@ public interface LinphoneCall {
|
|||
*/
|
||||
public static final State CallReleased = new State(18,"Released");
|
||||
|
||||
/**
|
||||
* The call is updated by remote while not yet answered (SIP UPDATE in early dialog received)
|
||||
*/
|
||||
public static final State CallEarlyUpdatedByRemote = new State(19,"EarlyUpdatedByRemote");
|
||||
|
||||
/**
|
||||
* We are updating the call while not yet answered (SIP UPDATE in early dialog sent)
|
||||
**/
|
||||
public static final State CallEarlyUpdating = new State(20,"EarlyUpdating");
|
||||
|
||||
private State(int value,String stringValue) {
|
||||
mValue = value;
|
||||
|
|
@ -333,4 +342,11 @@ public interface LinphoneCall {
|
|||
* @return an Object.
|
||||
*/
|
||||
Object getUserData();
|
||||
|
||||
/**
|
||||
* Get a call player
|
||||
* Call player enable to stream a media file through a call
|
||||
* @return A player
|
||||
*/
|
||||
public LinphonePlayer getPlayer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,6 +163,10 @@ public interface LinphoneChatMessage {
|
|||
*/
|
||||
void startFileDownload(LinphoneChatMessage.StateListener listener);
|
||||
|
||||
/**
|
||||
* Cancel an ongoing file transfer attached to this message.(upload or download).
|
||||
*/
|
||||
void cancelFileTransfer();
|
||||
/**
|
||||
* 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.
|
||||
|
|
@ -179,4 +183,5 @@ public interface LinphoneChatMessage {
|
|||
* @return the data stored in the chat message if any, else null
|
||||
*/
|
||||
String getAppData();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,9 +144,4 @@ public interface LinphoneChatRoom {
|
|||
*/
|
||||
LinphoneChatMessage createFileTransferMessage(LinphoneContent content);
|
||||
|
||||
/**
|
||||
* Cancel an ongoing file transfer attached to this message (upload or download)
|
||||
* @param message
|
||||
*/
|
||||
void cancelFileTransfer(LinphoneChatMessage message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1786,11 +1786,17 @@ public interface LinphoneCore {
|
|||
* Create a media player
|
||||
* @return An object that implement LinphonePlayer
|
||||
*/
|
||||
public LinphonePlayer createPlayer(AndroidVideoWindowImpl window);
|
||||
public LinphonePlayer createLocalPlayer(AndroidVideoWindowImpl window);
|
||||
|
||||
/**
|
||||
* Destroy a player
|
||||
* @param player Player to destroy
|
||||
* Adds a new listener to be called by the core
|
||||
* @param listener to add
|
||||
*/
|
||||
public void destroyPlayer(LinphonePlayer player);
|
||||
public void addListener(LinphoneCoreListener listener);
|
||||
|
||||
/**
|
||||
* Removes a listener previously added with addListener
|
||||
* @param listener to remove
|
||||
*/
|
||||
public void removeListener(LinphoneCoreListener listener);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,203 +22,226 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*This interface holds all callbacks that the application should implement. None is mandatory.
|
||||
*/
|
||||
public interface LinphoneCoreListener {
|
||||
/**< Ask the application some authentication information
|
||||
* @return */
|
||||
void authInfoRequested(LinphoneCore lc, String realm, String username, String Domain);
|
||||
|
||||
/** General State notification
|
||||
* @param state LinphoneCore.State
|
||||
* @return
|
||||
* */
|
||||
void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message);
|
||||
|
||||
/** Call State notification
|
||||
* @param state LinphoneCall.State
|
||||
* @return
|
||||
* */
|
||||
void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);
|
||||
|
||||
/**
|
||||
* Call stats notification
|
||||
*/
|
||||
void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);
|
||||
|
||||
/**
|
||||
* Callback to display change in encryption state.
|
||||
* @param encrypted true if all streams of the call are encrypted
|
||||
* @param authenticationToken token like ZRTP SAS that may be displayed to user
|
||||
*/
|
||||
void callEncryptionChanged(LinphoneCore lc, LinphoneCall call, boolean encrypted, String authenticationToken);
|
||||
|
||||
/**
|
||||
* Registration state notification
|
||||
* */
|
||||
void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);
|
||||
|
||||
/**
|
||||
* Reports that a new subscription request has been received and wait for a decision.
|
||||
*Status on this subscription request is notified by changing policy for this friend
|
||||
*@param lc LinphoneCore
|
||||
*@param lf LinphoneFriend corresponding to the subscriber
|
||||
*@param url of the subscriber
|
||||
*
|
||||
*/
|
||||
void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url);
|
||||
|
||||
/**
|
||||
* Report status change for a friend previously added to LinphoneCore.
|
||||
* @param lc LinphoneCore
|
||||
* @param lf updated LinphoneFriend
|
||||
*/
|
||||
void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);
|
||||
|
||||
/**
|
||||
* invoked when a new text message is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room.
|
||||
* @param from LinphoneAddress from
|
||||
* @param message incoming message
|
||||
*/
|
||||
void textReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneAddress from, String message);
|
||||
|
||||
/**
|
||||
* invoked when a new linphone chat message is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room.
|
||||
* @param message incoming linphone chat message message
|
||||
*/
|
||||
void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message);
|
||||
public interface LinphoneListener extends LinphoneCoreListener,
|
||||
LinphoneRemoteProvisioningListener, LinphoneMessageListener, LinphoneCallStateListener,
|
||||
LinphoneCallEncryptionStateListener, LinphoneNotifyListener, LinphoneComposingListener,
|
||||
LinphoneGlobalStateListener, LinphoneRegistrationStateListener {
|
||||
/**< Ask the application some authentication information
|
||||
* @return */
|
||||
void authInfoRequested(LinphoneCore lc, String realm, String username, String Domain);
|
||||
|
||||
/**
|
||||
* invoked when a composing notification is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in the conversation.
|
||||
*/
|
||||
void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr);
|
||||
/**
|
||||
* Call stats notification
|
||||
*/
|
||||
void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);
|
||||
|
||||
/**
|
||||
* invoked when a new dtmf is received
|
||||
* @param lc LinphoneCore
|
||||
* @param call LinphoneCall involved in the dtmf sending
|
||||
* @param dtmf value of the dtmf sent
|
||||
*/
|
||||
void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf);
|
||||
|
||||
/**
|
||||
* Invoked when echo cancalation calibration is completed
|
||||
* @param lc LinphoneCore
|
||||
* @param status
|
||||
* @param delay_ms echo delay
|
||||
* @param data
|
||||
*/
|
||||
void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);
|
||||
/**
|
||||
* Report Notified message received for this identity.
|
||||
* @param lc LinphoneCore
|
||||
* @param call LinphoneCall in case the notify is part of a dialog, may be null
|
||||
* @param from LinphoneAddress the message comes from
|
||||
* @param event String the raw body of the notify event.
|
||||
*
|
||||
*/
|
||||
void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event);
|
||||
/**
|
||||
* Reports that a new subscription request has been received and wait for a decision.
|
||||
*Status on this subscription request is notified by changing policy for this friend
|
||||
*@param lc LinphoneCore
|
||||
*@param lf LinphoneFriend corresponding to the subscriber
|
||||
*@param url of the subscriber
|
||||
*
|
||||
*/
|
||||
void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url);
|
||||
|
||||
/**
|
||||
* Notifies progress of a call transfer.
|
||||
* @param lc the LinphoneCore
|
||||
* @param call the call through which the transfer was sent.
|
||||
* @param new_call_state the state of the call resulting of the transfer, at the other party.
|
||||
**/
|
||||
void transferState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State new_call_state);
|
||||
|
||||
/**
|
||||
* Notifies an incoming INFO message.
|
||||
* @param lc the LinphoneCore.
|
||||
* @param info the info message
|
||||
*/
|
||||
void infoReceived(LinphoneCore lc, LinphoneCall call, LinphoneInfoMessage info);
|
||||
|
||||
/**
|
||||
* Notifies of subscription requests state changes, including new incoming subscriptions.
|
||||
* @param lc the LinphoneCore
|
||||
* @param ev LinphoneEvent object representing the subscription context.
|
||||
* @param state actual state of the subscription.
|
||||
*/
|
||||
void subscriptionStateChanged(LinphoneCore lc, LinphoneEvent ev, SubscriptionState state);
|
||||
|
||||
/**
|
||||
* Notifies of an incoming NOTIFY received.
|
||||
* @param lc the linphoneCore
|
||||
* @param ev a LinphoneEvent representing the subscription context for which this notify belongs, or null if it is a NOTIFY out of of any subscription.
|
||||
* @param eventName the event name
|
||||
* @param content content of the NOTIFY request.
|
||||
*/
|
||||
void notifyReceived(LinphoneCore lc, LinphoneEvent ev, String eventName, LinphoneContent content);
|
||||
/**
|
||||
* Notifies about outgoing generic publish states.
|
||||
* @param lc the LinphoneCore
|
||||
* @param ev a LinphoneEvent representing the publish, typically created by {@link LinphoneCore#publish}
|
||||
* @param state the publish state
|
||||
*/
|
||||
void publishStateChanged(LinphoneCore lc, LinphoneEvent ev, PublishState state);
|
||||
|
||||
/**
|
||||
* Notifies the changes about the remote provisioning step
|
||||
* @param lc the LinphoneCore
|
||||
* @param state the RemoteProvisioningState
|
||||
* @param message the error message if state == Failed
|
||||
*/
|
||||
void configuringStatus(LinphoneCore lc, RemoteProvisioningState state,
|
||||
String message);
|
||||
|
||||
/**< @Deprecated Notifies the application that it should show up
|
||||
* @return */
|
||||
void show(LinphoneCore lc);
|
||||
/**< @Deprecated Callback that notifies various events with human readable text.
|
||||
* @return */
|
||||
void displayStatus(LinphoneCore lc,String message);
|
||||
/**
|
||||
* Report status change for a friend previously added to LinphoneCore.
|
||||
* @param lc LinphoneCore
|
||||
* @param lf updated LinphoneFriend
|
||||
*/
|
||||
void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);
|
||||
|
||||
/**< @Deprecated Callback to display a message to the user
|
||||
* @return */
|
||||
void displayMessage(LinphoneCore lc,String message);
|
||||
/**
|
||||
* invoked when a new text message is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room.
|
||||
* @param from LinphoneAddress from
|
||||
* @param message incoming message
|
||||
*/
|
||||
void textReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneAddress from, String message);
|
||||
|
||||
/**
|
||||
* invoked when a new dtmf is received
|
||||
* @param lc LinphoneCore
|
||||
* @param call LinphoneCall involved in the dtmf sending
|
||||
* @param dtmf value of the dtmf sent
|
||||
*/
|
||||
void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf);
|
||||
|
||||
/**
|
||||
* Invoked when echo cancalation calibration is completed
|
||||
* @param lc LinphoneCore
|
||||
* @param status
|
||||
* @param delay_ms echo delay
|
||||
* @param data
|
||||
*/
|
||||
void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);
|
||||
|
||||
/**
|
||||
* Report Notified message received for this identity.
|
||||
* @param lc LinphoneCore
|
||||
* @param call LinphoneCall in case the notify is part of a dialog, may be null
|
||||
* @param from LinphoneAddress the message comes from
|
||||
* @param event String the raw body of the notify event.
|
||||
*
|
||||
*/
|
||||
void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event);
|
||||
|
||||
/** @Deprecated Callback to display a warning to the user
|
||||
* @return */
|
||||
void displayWarning(LinphoneCore lc,String message);
|
||||
/**
|
||||
* Notifies progress of a call transfer.
|
||||
* @param lc the LinphoneCore
|
||||
* @param call the call through which the transfer was sent.
|
||||
* @param new_call_state the state of the call resulting of the transfer, at the other party.
|
||||
**/
|
||||
void transferState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State new_call_state);
|
||||
|
||||
/**
|
||||
* Notifies an incoming INFO message.
|
||||
* @param lc the LinphoneCore.
|
||||
* @param info the info message
|
||||
*/
|
||||
void infoReceived(LinphoneCore lc, LinphoneCall call, LinphoneInfoMessage info);
|
||||
|
||||
/**
|
||||
* Notifies of subscription requests state changes, including new incoming subscriptions.
|
||||
* @param lc the LinphoneCore
|
||||
* @param ev LinphoneEvent object representing the subscription context.
|
||||
* @param state actual state of the subscription.
|
||||
*/
|
||||
void subscriptionStateChanged(LinphoneCore lc, LinphoneEvent ev, SubscriptionState state);
|
||||
|
||||
/**
|
||||
* Notifies about outgoing generic publish states.
|
||||
* @param lc the LinphoneCore
|
||||
* @param ev a LinphoneEvent representing the publish, typically created by {@link LinphoneCore#publish}
|
||||
* @param state the publish state
|
||||
*/
|
||||
void publishStateChanged(LinphoneCore lc, LinphoneEvent ev, PublishState state);
|
||||
|
||||
/**< @Deprecated Notifies the application that it should show up
|
||||
* @return */
|
||||
void show(LinphoneCore lc);
|
||||
|
||||
/**< @Deprecated Callback that notifies various events with human readable text.
|
||||
* @return */
|
||||
void displayStatus(LinphoneCore lc,String message);
|
||||
|
||||
/**< @Deprecated Callback to display a message to the user
|
||||
* @return */
|
||||
void displayMessage(LinphoneCore lc,String message);
|
||||
|
||||
/** @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
public interface LinphoneGlobalStateListener extends LinphoneCoreListener {
|
||||
/** General State notification
|
||||
* @param state LinphoneCore.State
|
||||
* @return
|
||||
* */
|
||||
void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
public interface LinphoneRegistrationStateListener extends LinphoneCoreListener {
|
||||
/**
|
||||
* Registration state notification
|
||||
* */
|
||||
void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState state, String smessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
public interface LinphoneRemoteProvisioningListener extends LinphoneCoreListener {
|
||||
/**
|
||||
* Notifies the changes about the remote provisioning step
|
||||
* @param lc the LinphoneCore
|
||||
* @param state the RemoteProvisioningState
|
||||
* @param message the error message if state == Failed
|
||||
*/
|
||||
void configuringStatus(LinphoneCore lc, RemoteProvisioningState state, String message);
|
||||
}
|
||||
|
||||
public interface LinphoneMessageListener extends LinphoneCoreListener {
|
||||
/**
|
||||
* invoked when a new linphone chat message is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room.
|
||||
* @param message incoming linphone chat message message
|
||||
*/
|
||||
void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message);
|
||||
}
|
||||
|
||||
public interface LinphoneCallStateListener extends LinphoneCoreListener {
|
||||
/** Call State notification
|
||||
* @param state LinphoneCall.State
|
||||
* @return
|
||||
* */
|
||||
void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State state, String message);
|
||||
}
|
||||
|
||||
public interface LinphoneCallEncryptionStateListener extends LinphoneCoreListener {
|
||||
/**
|
||||
* Callback to display change in encryption state.
|
||||
* @param encrypted true if all streams of the call are encrypted
|
||||
* @param authenticationToken token like ZRTP SAS that may be displayed to user
|
||||
*/
|
||||
void callEncryptionChanged(LinphoneCore lc, LinphoneCall call, boolean encrypted, String authenticationToken);
|
||||
}
|
||||
|
||||
public interface LinphoneNotifyListener extends LinphoneCoreListener {
|
||||
/**
|
||||
* Notifies of an incoming NOTIFY received.
|
||||
* @param lc the linphoneCore
|
||||
* @param ev a LinphoneEvent representing the subscription context for which this notify belongs, or null if it is a NOTIFY out of of any subscription.
|
||||
* @param eventName the event name
|
||||
* @param content content of the NOTIFY request.
|
||||
*/
|
||||
void notifyReceived(LinphoneCore lc, LinphoneEvent ev, String eventName, LinphoneContent content);
|
||||
}
|
||||
|
||||
public interface LinphoneComposingListener extends LinphoneCoreListener {
|
||||
/**
|
||||
* invoked when a composing notification is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in the conversation.
|
||||
*/
|
||||
void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ public interface LinphonePlayer {
|
|||
*
|
||||
*/
|
||||
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 */
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -245,4 +245,10 @@ class LinphoneCallImpl implements LinphoneCall {
|
|||
public Object getUserData() {
|
||||
return userData;
|
||||
}
|
||||
|
||||
private native long getPlayer(long callPtr);
|
||||
@Override
|
||||
public LinphonePlayer getPlayer() {
|
||||
return new LinphonePlayerImpl(getPlayer(nativePtr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package org.linphone.core;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class LinphoneChatMessageImpl implements LinphoneChatMessage {
|
||||
protected final long nativePtr;
|
||||
private native String getText(long ptr);
|
||||
private native byte[] getText(long ptr);
|
||||
private native long getPeerAddress(long ptr);
|
||||
private native String getExternalBodyUrl(long ptr);
|
||||
private native void setExternalBodyUrl(long ptr, String url);
|
||||
|
|
@ -25,7 +27,12 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
|
|||
|
||||
@Override
|
||||
public String getText() {
|
||||
return getText(nativePtr);
|
||||
try {
|
||||
return new String(getText(nativePtr), "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -127,4 +134,10 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
|
|||
public String getAppData() {
|
||||
return getAppData(nativePtr);
|
||||
}
|
||||
|
||||
private native void cancelFileTransfer(long messagePtr);
|
||||
@Override
|
||||
public void cancelFileTransfer() {
|
||||
cancelFileTransfer(nativePtr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,11 +177,4 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
|
|||
}
|
||||
}
|
||||
|
||||
private native void cancelFileTransfer(long ptr, long messagePtr);
|
||||
@Override
|
||||
public void cancelFileTransfer(LinphoneChatMessage message) {
|
||||
synchronized(getCore()) {
|
||||
cancelFileTransfer(nativePtr, ((LinphoneChatMessageImpl)message).getNativePtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,13 +48,9 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
|
|||
|
||||
// FFMPEG (audio/video)
|
||||
if (Version.isX86()) {
|
||||
loadOptionalLibrary("avutil-linphone-x86");
|
||||
loadOptionalLibrary("swscale-linphone-x86");
|
||||
loadOptionalLibrary("avcodec-linphone-x86");
|
||||
loadOptionalLibrary("ffmpeg-linphone-x86");
|
||||
} else if (Version.isArmv7()) {
|
||||
loadOptionalLibrary("avutil-linphone-arm");
|
||||
loadOptionalLibrary("swscale-linphone-arm");
|
||||
loadOptionalLibrary("avcodec-linphone-arm");
|
||||
loadOptionalLibrary("ffmpeg-linphone-arm");
|
||||
}
|
||||
|
||||
//Main library
|
||||
|
|
@ -102,7 +98,9 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
|
|||
public LinphoneCore createLinphoneCore(LinphoneCoreListener listener, Object context) throws LinphoneCoreException {
|
||||
try {
|
||||
MediastreamerAndroidContext.setContext(context);
|
||||
return new LinphoneCoreImpl(listener);
|
||||
LinphoneCore lc = new LinphoneCoreImpl(listener);
|
||||
if(context!=null) lc.setContext(context);
|
||||
return lc;
|
||||
} catch (IOException e) {
|
||||
throw new LinphoneCoreException("Cannot create LinphoneCore",e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
return logs;
|
||||
}
|
||||
public synchronized void destroy() {
|
||||
setAndroidPowerManager(null);
|
||||
delete(nativePtr);
|
||||
nativePtr=0;
|
||||
}
|
||||
|
|
@ -1280,10 +1281,10 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
return getFileTransferServer(nativePtr);
|
||||
}
|
||||
|
||||
private native long createPlayer(long nativePtr, AndroidVideoWindowImpl window);
|
||||
private native long createLocalPlayer(long nativePtr, AndroidVideoWindowImpl window);
|
||||
@Override
|
||||
public synchronized LinphonePlayer createPlayer(AndroidVideoWindowImpl window) {
|
||||
long playerPtr = createPlayer(nativePtr, window);
|
||||
public synchronized LinphonePlayer createLocalPlayer(AndroidVideoWindowImpl window) {
|
||||
long playerPtr = createLocalPlayer(nativePtr, window);
|
||||
if(playerPtr != 0) {
|
||||
return new LinphonePlayerImpl(playerPtr);
|
||||
} else {
|
||||
|
|
@ -1291,9 +1292,15 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
}
|
||||
}
|
||||
|
||||
private native void destroyPlayer(long playerPtr);
|
||||
private native void addListener(long nativePtr, LinphoneCoreListener listener);
|
||||
@Override
|
||||
public synchronized void destroyPlayer(LinphonePlayer player) {
|
||||
|
||||
public void addListener(LinphoneCoreListener listener) {
|
||||
addListener(nativePtr, listener);
|
||||
}
|
||||
|
||||
private native void removeListener(long nativePtr, LinphoneCoreListener listener);
|
||||
@Override
|
||||
public void removeListener(LinphoneCoreListener listener) {
|
||||
removeListener(nativePtr, listener);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,4 +61,10 @@ public class LinphonePlayerImpl implements LinphonePlayer {
|
|||
public synchronized void close() {
|
||||
close(nativePtr);
|
||||
}
|
||||
|
||||
private native void destroy(long nativePtr);
|
||||
@Override
|
||||
protected void finalize() {
|
||||
destroy(nativePtr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,12 @@
|
|||
AC_DEFUN([LP_CHECK_READLINE],[
|
||||
|
||||
AC_ARG_WITH( readline,
|
||||
[ --with-readline Set prefix where gnu readline headers and libs can be found (ex:/usr, /usr/local, none) [default=/usr] ],
|
||||
[ readline_prefix=${withval}],[ readline_prefix="/usr" ])
|
||||
[ --with-readline Set prefix where gnu readline headers and libs can be found (ex:/usr, /usr/local, none) [default=/usr] ],
|
||||
[ readline_prefix=${withval} ],
|
||||
[ readline_prefix="/usr/local" ],
|
||||
[ readline_prefix="/opt/local" ],
|
||||
[ readline_prefix="/usr" ]
|
||||
)
|
||||
|
||||
if test "$readline_prefix" != "none"; then
|
||||
|
||||
|
|
@ -14,14 +18,14 @@ if test "$readline_prefix" != "none"; then
|
|||
READLINE_CFLAGS="-I$readline_prefix/include"
|
||||
READLINE_LIBS="-L$readline_prefix/lib"
|
||||
fi
|
||||
|
||||
|
||||
CPPFLAGS_save=$CPPFLAGS
|
||||
LIBS_save=$LIBS
|
||||
CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS"
|
||||
LIBS="$LIBS $READLINE_LIBS"
|
||||
AC_CHECK_HEADERS(readline.h readline/readline.h, readline_h_found=yes)
|
||||
AC_CHECK_HEADERS(history.h readline/history.h)
|
||||
|
||||
|
||||
for termcap_lib in "" -ltermcap -lcurses -lncurses; do
|
||||
unset ac_cv_lib_readline_readline
|
||||
AC_CHECK_LIB(readline, readline, [readline_libs_found=yes],[],[$termcap_lib])
|
||||
|
|
@ -33,14 +37,14 @@ if test "$readline_prefix" != "none"; then
|
|||
|
||||
LIBS=$LIBS_save
|
||||
CPPFLAGS=$CPPFLAGS_save
|
||||
|
||||
|
||||
if test "$readline_libs_found$readline_h_found" != "yesyes" ; then
|
||||
AC_MSG_WARN([Could not find libreadline headers or library, linphonec will have limited prompt features])
|
||||
else
|
||||
AC_DEFINE([HAVE_READLINE],1,[defined when compiling with readline support])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
AC_SUBST(READLINE_CFLAGS)
|
||||
AC_SUBST(READLINE_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 2fa9c8e258eacadc789f87d3ea3a152faea291ea
|
||||
Subproject commit 06a14487aa5acc0e3f0d4931c9a974762829d7bd
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 05e0242a91391747408340dffa34f9b4e1335be4
|
||||
Subproject commit a3debbd394fb32ab54ed265d2190711971c890e7
|
||||
64
pixmaps/CMakeLists.txt
Normal file
64
pixmaps/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
############################################################################
|
||||
# CMakeLists.txt
|
||||
# Copyright (C) 2014 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
set(PIXMAPS
|
||||
active_chat.png
|
||||
addcall-green.png
|
||||
call.png
|
||||
call_status_incoming.png
|
||||
call_status_outgoing.png
|
||||
chat_message_delivered.png
|
||||
chat_message_inprogress.png
|
||||
chat_message_not_delivered.png
|
||||
chat.png
|
||||
composing_active_chat.png
|
||||
composing_chat.png
|
||||
contact-orange.png
|
||||
contact_starred.png
|
||||
contact_unstarred.png
|
||||
dialer-orange.png
|
||||
dialer.png
|
||||
history-orange.png
|
||||
hold_off.png
|
||||
hold_on.png
|
||||
linphone-banner.png
|
||||
linphone.icns
|
||||
linphone.png
|
||||
mic_active.png
|
||||
mic_muted.png
|
||||
notok.png
|
||||
ok.png
|
||||
speaker.png
|
||||
startcall-green.png
|
||||
startcall-small.png
|
||||
status-green.png
|
||||
status-offline.png
|
||||
status-orange.png
|
||||
status-red.png
|
||||
stopcall-red.png
|
||||
stopcall-small.png
|
||||
)
|
||||
|
||||
install(FILES ${PIXMAPS}
|
||||
DESTINATION ${PACKAGE_DATA_DIR}/pixmaps/linphone
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
|
|
@ -40,3 +40,5 @@ coreapi/proxy.c
|
|||
coreapi/callbacks.c
|
||||
coreapi/linphonecall.c
|
||||
|
||||
coreapi/call_log.c
|
||||
gtk/videowindow.c
|
||||
|
|
|
|||
|
|
@ -48,3 +48,6 @@ mediastreamer2/src/videofilters/winvideo2.c
|
|||
mediastreamer2/src/videofilters/x11video.c
|
||||
mediastreamer2/src/voip/ice.c
|
||||
build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Resources/AppResources.Designer.cs
|
||||
build/wp8/LibLinphoneTester-wp8/Resources/AppResources.Designer.cs
|
||||
mediastreamer2/build/wp8/mediastreamer2-tester-wp8/Resources/AppResources.Designer.cs
|
||||
share/linphone.desktop.in
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue