forked from mirrors/linphone-iphone
Merge remote-tracking branch 'linphone-public/master' into dev_lime
This commit is contained in:
commit
d133ebd5eb
216 changed files with 22680 additions and 20349 deletions
|
|
@ -22,7 +22,7 @@
|
|||
<folderInfo id="0.2079208171." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071.81924294" name=""/>
|
||||
<builder arguments="-j4 CFLAGS="-g -Wall -Werror -Qunused-arguments" CXXFLAGS="-g"" autoBuildTarget="all" cleanBuildTarget="clean" command="make" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.731584538" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<builder arguments="-j4" autoBuildTarget="all" cleanBuildTarget="clean" command="make" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.731584538" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1252970003" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1371414073" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.306286573" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -78,3 +78,7 @@ Linphone.app
|
|||
*.dmg
|
||||
tester/linphone*.log
|
||||
tester/linphone_log.txt
|
||||
.tx/linphone-gtk.linphonedesktopin/
|
||||
po/linphone.pot
|
||||
.tx/linphone-gtk.audio-assistantdesktopin/
|
||||
tester/linphone_log.gz.txt
|
||||
|
|
|
|||
20
.tx/config
Normal file
20
.tx/config
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[main]
|
||||
host = https://www.transifex.com
|
||||
minimum_perc = 1
|
||||
|
||||
[linphone-gtk.linphonepot]
|
||||
file_filter = po/<lang>.po
|
||||
source_file = po/linphone.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[linphone-gtk.linphonedesktopin]
|
||||
source_file = share/linphone.desktop.in
|
||||
source_lang = en
|
||||
type = DESKTOP
|
||||
|
||||
[linphone-gtk.audio-assistantdesktopin]
|
||||
source_file = share/audio-assistant.desktop.in
|
||||
source_lang = en
|
||||
type = DESKTOP
|
||||
|
||||
109
CMakeLists.txt
109
CMakeLists.txt
|
|
@ -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,24 +52,65 @@ 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_MSG_STORAGE)
|
||||
find_package(Sqlite3)
|
||||
if(NOT SQLITE3_FOUND)
|
||||
message(FATAL_ERROR "Could not find the sqlite3 library!")
|
||||
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()
|
||||
if(ENABLE_ASSISTANT)
|
||||
find_package(Soup)
|
||||
if(SOUP_FOUND)
|
||||
set(BUILD_WIZARD 1)
|
||||
else()
|
||||
message(WARNING "Could not find the soup library!")
|
||||
set(ENABLE_ASSISTANT OFF CACHE BOOL "Turn on assistant compiling." FORCE)
|
||||
endif()
|
||||
endif()
|
||||
find_package(Gettext)
|
||||
|
||||
|
||||
include_directories(
|
||||
|
|
@ -79,15 +122,44 @@ include_directories(
|
|||
${MS2_INCLUDE_DIRS}
|
||||
${XML2_INCLUDE_DIRS}
|
||||
)
|
||||
if(SQLITE3_FOUND)
|
||||
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||
add_definitions("-DMSG_STORAGE_ENABLED")
|
||||
endif()
|
||||
if(ENABLE_TUNNEL)
|
||||
include_directories(${TUNNEL_INCLUDE_DIRS})
|
||||
endif()
|
||||
if(ENABLE_ASSISTANT)
|
||||
include_directories(${SOUP_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
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 +169,36 @@ 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)
|
||||
add_subdirectory(po)
|
||||
endif()
|
||||
if(ENABLE_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif()
|
||||
if(ENABLE_UNIT_TESTS)
|
||||
add_subdirectory(tester)
|
||||
endif()
|
||||
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLinphone.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindLinphone.cmake)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FindLinphone.cmake
|
||||
DESTINATION share/cmake/Modules
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
|
|
|
|||
25
Makefile.am
25
Makefile.am
|
|
@ -7,6 +7,8 @@ SUBDIRS = build m4 pixmaps po @ORTP_DIR@ @MS2_DIR@ \
|
|||
coreapi console gtk share scripts tools tester include
|
||||
|
||||
|
||||
GITVERSION=`cd $(top_srcdir) && git describe --always || echo $(VERSION)`
|
||||
|
||||
|
||||
ACLOCAL_FLAGS=-I$(top_srcdir)/m4
|
||||
|
||||
|
|
@ -20,11 +22,11 @@ OPTIONAL_SOUNDS=\
|
|||
|
||||
INSTALLDIR=$(abs_top_builddir)/linphone-install
|
||||
INSTALLDIR_WITH_PREFIX=$(INSTALLDIR)/$(prefix)
|
||||
ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-win32-$(VERSION).zip
|
||||
ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-win32-$(GITVERSION).zip
|
||||
ZIP_EXCLUDED=include lib \
|
||||
$(OPTIONAL_SOUNDS)
|
||||
|
||||
SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-$(VERSION).zip
|
||||
SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-sdk-$(GITVERSION).zip
|
||||
SDK_EXCLUDED= \
|
||||
bin/linphone.exe \
|
||||
lib/*.la \
|
||||
|
|
@ -166,6 +168,15 @@ filelist: zip
|
|||
fi \
|
||||
done
|
||||
|
||||
### LOCALIZATION
|
||||
|
||||
pull-transifex:
|
||||
tx pull -af
|
||||
$(MAKE) -C po update-po
|
||||
|
||||
push-transifex:
|
||||
tx push -s -t -f --no-interactive
|
||||
|
||||
|
||||
### WINDOWS
|
||||
|
||||
|
|
@ -173,7 +184,7 @@ setup.exe: filelist
|
|||
cp $(ISS_SCRIPT) $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cd $(INSTALLDIR_WITH_PREFIX) && \
|
||||
$(ISCC) $(ISS_SCRIPT)
|
||||
mv $(INSTALLDIR_WITH_PREFIX)/Output/setup.exe $(PACKAGE)-$(VERSION)-setup.exe
|
||||
mv $(INSTALLDIR_WITH_PREFIX)/Output/setup.exe $(PACKAGE)-setup-$(GITVERSION).exe
|
||||
rm -rf $(INSTALLDIR_WITH_PREFIX)/Output
|
||||
rm -f $(INSTALLDIR_WITH_PREFIX)/$(PACKAGE_WIN32_FILELIST)
|
||||
rm -f $(INSTALLDIR_WITH_PREFIX)/$(ISS_SCRIPT)
|
||||
|
|
@ -201,11 +212,12 @@ Portfile-devel: $(top_srcdir)/scripts/Portfile-devel.tmpl dist
|
|||
### MAC
|
||||
|
||||
MACAPPNAME=Linphone.app
|
||||
MACAPPZIP=$(PACKAGE)-$(VERSION).app.zip
|
||||
MACAPPDMG=$(PACKAGE)-$(VERSION).dmg
|
||||
MACAPPZIP=$(PACKAGE)-$(GITVERSION).app.zip
|
||||
MACAPPDMG=$(PACKAGE)-$(GITVERSION).dmg
|
||||
BUNDLEPREFIX=./
|
||||
BUNDLEDIR=$(BUNDLEPREFIX)$(MACAPPNAME)
|
||||
|
||||
#a path prefix where additional libs can be cherry-picked by the bundler.
|
||||
LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX=/usr/local
|
||||
|
||||
bundle:
|
||||
rm -rf $(INSTALLDIR)
|
||||
|
|
@ -215,6 +227,7 @@ bundle:
|
|||
LINPHONE_INSTALL_PREFIX=$(INSTALLDIR_WITH_PREFIX) \
|
||||
LIBLINPHONE_INSTALL_PREFIX=$(INSTALLDIR_WITH_PREFIX) \
|
||||
MS2_PLUGINS_INSTALL_PREFIX=$(prefix) \
|
||||
LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX=$(LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX) \
|
||||
gtk-mac-bundler $(PACKAGE_BUNDLE_FILE)
|
||||
printf "[Pango]\nModuleFiles=./etc/pango/pango.modules\n" \
|
||||
> $(BUNDLEDIR)/Contents/Resources/etc/pango/pangorc
|
||||
|
|
|
|||
26
NEWS
26
NEWS
|
|
@ -1,3 +1,29 @@
|
|||
linphone-3.8.0 -- Date to be defined
|
||||
Application level improvements:
|
||||
* The video window has now controls in order to switch fullscreen mode and terminate call.
|
||||
* The out of call video preview feature (to test camera) is moved into the settings and is no longer linked to the in-call video preview feature.
|
||||
* Add an assistant to help users to set audio/video parameters
|
||||
* Some ergonomics improvments (checkbox to set random port for UDP and TCP, ...)
|
||||
* Lots of updated translations. Arabic translation has been added
|
||||
* Experimental feature: play an MKV file by drag-and-dropping it on the video call window
|
||||
|
||||
Liblinphone level improvements:
|
||||
* Support for RTP/AVPF (RFC4585) for video streams, allowing fast transmission error recovery with VP8 codec only.
|
||||
* API enhancements, most objects can be ref-counted.
|
||||
* Add some getter funtctions to the call information API
|
||||
* Add a function in the API to accept early-media calls
|
||||
* Add a function to set the SIP transport timeout
|
||||
* Add a function to change adaptive rate algorithm at runtime
|
||||
* Add support of file transfer
|
||||
* Call video recording feature, in mkv format (H264 streams only for the moment)
|
||||
* Call playing feature: play an MKV file and send the audio/video stream through a call
|
||||
* Local player API. Play WAV and MKV file and display video on a specified window display
|
||||
* A wrapper for Python has been made
|
||||
* Support of Wake Locks on Android
|
||||
* Support of multicast IP addresses
|
||||
* Support of incoming UPDATEs within dialog (RFC3311)
|
||||
* Support of SRTP by using packages from GNU/Linux distributions
|
||||
|
||||
linphone-3.7.0 -- February 20th, 2014
|
||||
Application level improvements:
|
||||
* It is now possible to configure multiple proxy accounts with different transports (UDP, TCP, TLS)
|
||||
|
|
|
|||
7
README
7
README
|
|
@ -39,12 +39,7 @@ libglew1.6-dev libv4l-dev libxml2-dev
|
|||
|
||||
+ for optional library
|
||||
$ sudo apt-get install libreadline-dev libgsm1-dev libtheora-dev \
|
||||
libsoup2.4-dev libsqlite3-dev libupnp4-dev
|
||||
|
||||
+ Install srtp (optional) for call encryption :
|
||||
$ git clone git://git.linphone.org/srtp.git
|
||||
$ cd srtp && autoconf && ./configure && make
|
||||
$ sudo make install
|
||||
libsoup2.4-dev libsqlite3-dev libupnp4-dev libsrtp-dev
|
||||
|
||||
+ Install zrtp (optional), for unbreakable call encryption
|
||||
$ git clone git://git.linphone.org:bzrtp
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
# Compiling Linphone on MacOS X
|
||||
# Linphone on MacOS X
|
||||
|
||||
## Dependencies
|
||||
## Build prerequisite
|
||||
|
||||
* Xcode (download from apple or using appstore application)
|
||||
* Java SE
|
||||
* [Java SE](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or openJDK
|
||||
This is required to generate a C sourcefile from SIP grammar using [antlr3](http://www.antlr3.org/) generator.
|
||||
* [HomeBrew](http://brew.sh) or [Macports](http://www.macports.org/).
|
||||
|
||||
### Multiple MacOS version support
|
||||
### Dependencies
|
||||
|
||||
#### Using MacPorts
|
||||
|
||||
##### Multiple MacOS version support
|
||||
|
||||
In order to enable generation of bundle for multiple MacOS version and 32 bit processors, it is recommended to:
|
||||
|
||||
|
|
@ -18,17 +23,16 @@ In order to enable generation of bundle for multiple MacOS version and 32 bit pr
|
|||
|
||||
> +universal
|
||||
|
||||
### Build time dependencies
|
||||
|
||||
#### Using MacPorts
|
||||
##### Linphone library (liblinphone)
|
||||
|
||||
* Linphone core dependencies
|
||||
|
||||
sudo port install automake autoconf libtool intltool wget cunit \
|
||||
sudo port install automake autoconf libtool pkgconfig 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.
|
||||
##### Linphone UI (GTK version)
|
||||
|
||||
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
|
||||
|
|
@ -36,25 +40,22 @@ In order to enable generation of bundle for multiple MacOS version and 32 bit pr
|
|||
|
||||
#### 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
|
||||
##### Linphone library (liblinphone)
|
||||
|
||||
brew tap Gui13/linphone
|
||||
brew install intltool libtool wget pkg-config automake libantlr3.4c \
|
||||
antlr3.2 gettext speex ffmpeg readline libvpx opus
|
||||
ln -s /usr/local/bin/glibtoolize /usr/local/bin/libtoolize
|
||||
brew link --force gettext
|
||||
|
||||
##### Linphone UI (GTK version)
|
||||
|
||||
brew install cairo --without-x11
|
||||
brew install gtk+ --without-x11
|
||||
brew install gettext gtk-mac-integration libsoup hicolor-icon-theme
|
||||
#readline is required from linphonec.c otherwise compilation will fail
|
||||
brew link readline --force
|
||||
|
||||
# then you have to install antlr3 from a tap.
|
||||
wget https://gist.githubusercontent.com/Gui13/f5cf103f50d34c28c7be/raw/f50242f5e0c3a6d25ed7fca1462bce3a7b738971/antlr3.rb
|
||||
mv antlr3.rb /usr/local/Library/Formula/
|
||||
brew install antlr3
|
||||
|
||||
brew tap marekjelen/gtk
|
||||
brew install gtk+-quartz
|
||||
|
||||
# gtk-mac-integration is not available in main repository or Brew yet.
|
||||
wget https://gist.github.com/Gui13/cdcad37faa6b8ffa0588/raw/bf2277d45e261ad48ae1344c4c97f2684974ed87/gtk-mac-integration.rb
|
||||
mv gtk-mac-integration.rb /usr/local/Library/Formula/
|
||||
brew install gtk-mac-integration
|
||||
|
||||
### Building Linphone
|
||||
|
||||
The next pieces need to be compiled manually.
|
||||
|
|
@ -67,7 +68,7 @@ The next pieces need to be compiled manually.
|
|||
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)
|
||||
* (MacPorts only) Install libantlr3c (library used by belle-sip for parsing)
|
||||
|
||||
git clone -b linphone git://git.linphone.org/antlr3.git
|
||||
cd antlr3/runtime/C
|
||||
|
|
@ -121,14 +122,12 @@ The libvpx build isn't able to produce dual architecture files. To workaround th
|
|||
If you got the source code from git, run `./autogen.sh` first.
|
||||
Then or otherwise, :
|
||||
|
||||
# HomeBrew
|
||||
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 --with-readline=/usr/local && make
|
||||
# MacPorts
|
||||
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 --with-readline=/opt/local && make
|
||||
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --prefix=/opt/local --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
|
||||
|
|
@ -138,7 +137,7 @@ 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:
|
||||
# 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`.
|
||||
|
|
@ -148,6 +147,15 @@ If you don't need plugins, remove or comment out this line from the bundler file
|
|||
${prefix:ms2plugins}/lib/mediastreamer/plugins/*.*.so
|
||||
</binary>
|
||||
|
||||
If using HomeBrew, this is not working yet. However you will at least need to:
|
||||
|
||||
brew install shared-mime-info glib-networking hicolor-icon-theme
|
||||
update-mime-database /usr/local/share/mime
|
||||
|
||||
And modify also:
|
||||
|
||||
<prefix name="default">/usr/local</prefix>
|
||||
|
||||
Then run, inside Linphone source tree configure as told before but with `--enable-relativeprefix` appended.
|
||||
|
||||
make && make bundle
|
||||
|
|
|
|||
81
README.mingw
81
README.mingw
|
|
@ -29,7 +29,8 @@ Download lastest linphone-deps-win32 zip from
|
|||
http://download.savannah.gnu.org/releases-noredirect/linphone/misc
|
||||
using your browser.
|
||||
|
||||
Download gtk+-2.24.10 win32 _bundle_ from http://www.gtk.org, direct link: http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip
|
||||
Download gtk+-2.24.10 win32 _bundle_ from http://www.gtk.org, direct link:
|
||||
http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip
|
||||
|
||||
Install all these three package in /:
|
||||
|
||||
|
|
@ -46,26 +47,35 @@ tar -xvzf GTK2-Outcrop.tar.gz
|
|||
#To get the translations working, remove from C:/MinGW/lib :
|
||||
libintl.a libintl.la libintl.dll.a
|
||||
|
||||
* Download and install Inno Setup Compiler (required only if you run 'make setup.exe'). Add it to your windows Path environment variable.
|
||||
* Download and install Inno Setup Compiler (required only if you run
|
||||
'make setup.exe'). Add it to your windows Path environment variable.
|
||||
|
||||
* Install msys-git from (http://msysgit.github.io/). During installation you are asked to make a choice about how line endings are treated by git. Choose "Checkout line endings as they are, commit as they are". THIS CHOICE IS VERY IMPORTANT. OTHERS BREAK AUTOMAKE.
|
||||
* Install msys-git from (http://msysgit.github.io/). During installation you
|
||||
are asked to make a choice about how line endings are treated by git. Choose
|
||||
"Checkout line endings as they are, commit as they are". THIS CHOICE IS VERY
|
||||
IMPORTANT. OTHERS BREAK AUTOMAKE.
|
||||
|
||||
|
||||
General rules for compilation
|
||||
*****************************
|
||||
|
||||
- It is recommended that you create a directory somewhere with a path without any spaces or ~ characters, for example c:\sources\.
|
||||
This is the place where source code must be compiled.
|
||||
- git commands (to retrieve source code) must be performed within msys-git terminal.
|
||||
- all other commands (configure, autogen.sh, make) must be done within the mingw shell (msys).
|
||||
In both msys and msys-git windows, change into the directory you created for sources:
|
||||
cd /c/sources
|
||||
- make sure pkg-config works by adding this env variable to your terminal:
|
||||
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
* It is recommended that you create a directory somewhere with a path without
|
||||
any spaces or ~ characters, for example c:\sources\. This is the place where
|
||||
source code must be compiled.
|
||||
* git commands (to retrieve source code) must be performed within msys-git
|
||||
terminal.
|
||||
* all other commands (configure, autogen.sh, make) must be done within the
|
||||
mingw shell (msys). In both msys and msys-git windows, change into the
|
||||
directory you created for sources:
|
||||
cd /c/sources
|
||||
|
||||
* make sure pkg-config works by adding this env variable to your terminal:
|
||||
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
|
||||
Building belle-sip
|
||||
******************
|
||||
* make sure that java version 1.6 is available in the PATH. java-1.7 will not work with antlr generator.
|
||||
* make sure that java version 1.6 is available in the PATH. java-1.7 will
|
||||
not work with antlr generator.
|
||||
* download the sources with msys-git shell using the following command:
|
||||
$ git clone git://git.linphone.org/belle-sip.git
|
||||
* compile and install
|
||||
|
|
@ -80,11 +90,12 @@ Building Linphone
|
|||
$ git clone git://git.linphone.org/linphone.git --recursive
|
||||
|
||||
* compile
|
||||
#always run autogen.sh after a git checkout or update
|
||||
#always run autogen.sh after a git checkout or update
|
||||
$ ./autogen.sh
|
||||
|
||||
$ ./configure --prefix=/usr --enable-shared --disable-static
|
||||
#note: in order to use the tunnel (commercial extension), append --enable-tunnel to the configure line above.
|
||||
#note: in order to use the tunnel (commercial extension), append
|
||||
#--enable-tunnel to the configure line above.
|
||||
|
||||
$ make
|
||||
$ make install
|
||||
|
|
@ -92,15 +103,18 @@ Building Linphone
|
|||
#Option: make a portable binary zip of linphone
|
||||
$ make zip
|
||||
|
||||
#additionally you can make binary installer if you have Inno Setup 5 installed in its default path
|
||||
#additionally you can make binary installer if you have Inno Setup 5
|
||||
installed in its default path
|
||||
|
||||
$ make setup.exe
|
||||
#now you're done, you have a fresh linphone windows installer in the current directory.
|
||||
#now you're done, you have a fresh linphone windows installer in the
|
||||
current directory.
|
||||
|
||||
Building plugins (optional)
|
||||
***************************
|
||||
|
||||
This the example for msx264 (H264 plugin), the same applies for other linphone plugins.
|
||||
This the example for msx264 (H264 plugin), the same applies for other
|
||||
linphone plugins.
|
||||
$ git clone git://git.linphone.org/msx264.git
|
||||
$ cd msx264
|
||||
$ ./autogen.sh
|
||||
|
|
@ -115,17 +129,17 @@ Building plugins (optional)
|
|||
* Notes about linphone-deps generation *
|
||||
******************************************************
|
||||
|
||||
Linphone-deps is a collection of linphone dependencies, that are for some of them difficult
|
||||
to find as windows binaries.
|
||||
These notes are useful if you want to upgrade part of the software that is included in the
|
||||
linphone-deps packages.
|
||||
Linphone-deps is a collection of linphone dependencies, that are for some of
|
||||
them difficult to find as windows binaries. These notes are useful if you want
|
||||
to upgrade part of the software that is included in the linphone-deps packages.
|
||||
|
||||
List of software included in linphone-deps:
|
||||
antlr3c (compiled)
|
||||
bzrtp (compiled)
|
||||
polarssl (compiled
|
||||
libsrtp (compiled)
|
||||
libavcodec, libavutil, libavformat, libavdevice, libswscale (compiled, all these from ffmpeg)
|
||||
libavcodec, libavutil, libavformat, libavdevice, libswscale (compiled, all
|
||||
these from ffmpeg)
|
||||
libtheora (from the web)
|
||||
libx264 (compiled from the version distributed from linphone's web site)
|
||||
libogg (from the web)
|
||||
|
|
@ -137,8 +151,10 @@ libsoup (compiled)
|
|||
libsqlite3 (compiled)
|
||||
|
||||
Remarks:
|
||||
For every package compiled that goes into linphone-deps, .la files (libtool files) must be removed to avoid libtool errors.
|
||||
When running "make install DESTDIR=<somepath>", somepath must be absolute and should not contain any ~ or space.
|
||||
For every package compiled that goes into linphone-deps, .la files (libtool
|
||||
files) must be removed to avoid libtool errors. When running "make install
|
||||
DESTDIR=<somepath>", somepath must be absolute and should not contain any ~ or
|
||||
space.
|
||||
|
||||
- building antlr3c
|
||||
* download the sources with:
|
||||
|
|
@ -192,9 +208,12 @@ When running "make install DESTDIR=<somepath>", somepath must be absolute and sh
|
|||
./configure --enable-shared --disable-static --enable-memalign-hack --extra-cflags="-fno-common" --enable-gpl && make
|
||||
make install DESTDIR=/home/<myuser>/ffmpeg-install
|
||||
Copy to ~/ffmpeg-install/usr/local/* to linphone-deps/.
|
||||
Copy also all *.dll.a files from the build tree to lib/ directort of linphone-deps. These are the implibs necessary to link a program against the dlls.
|
||||
Copy also all *.dll.a files from the build tree to lib/ directort of
|
||||
linphone-deps. These are the implibs necessary to link a program against the
|
||||
dlls.
|
||||
|
||||
- building libxml2: the binaries found on the internet are generated with MSVC++, and for obscure reason they are not suitable for building libsoup
|
||||
- building libxml2: the binaries found on the internet are generated with
|
||||
MSVC++, and for obscure reason they are not suitable for building libsoup
|
||||
(that requires libxml2).
|
||||
./configure --enable-shared --disable-static && make && make install DESTDIR=/home/<myuser>/libxml2-install
|
||||
copy ~/libxml2-install/usr/local/* into linphone-deps/.
|
||||
|
|
@ -217,12 +236,14 @@ When running "make install DESTDIR=<somepath>", somepath must be absolute and sh
|
|||
- add to linphone-deps
|
||||
|
||||
- building libsoup (only required for buddylookup plugin)
|
||||
- download source from gnome ftp (warning: at the time of the writing only version 2.26.x can compile with the
|
||||
glib version supplied in the gtk-bundle, 2.27 requires a new version of glib)
|
||||
- download source from gnome ftp (warning: at the time of the writing
|
||||
only version 2.26.x can compile with the glib version supplied in the
|
||||
gtk-bundle, 2.27 requires a new version of glib)
|
||||
- uncompress libgnutls zip in /
|
||||
- make sure you have libxml2 installed in /
|
||||
- apply a bugfix patch (fix gnutls support on windows, completely broken otherwise). The patch
|
||||
is in linphone-deps/src, apply it this way:
|
||||
- apply a bugfix patch (fix gnutls support on windows, completely
|
||||
broken otherwise). The patch is in linphone-deps/src, apply it this
|
||||
way:
|
||||
cd libsoup-2.26.*
|
||||
cd libsoup
|
||||
patch -p0 < libsoup-gnutls-bugfix.patch
|
||||
|
|
|
|||
2
TODO
2
TODO
|
|
@ -3,7 +3,7 @@ hot stuff:
|
|||
|
||||
* ice support
|
||||
* run a user given command upon incoming calls
|
||||
* SIP/TLS and SRTP
|
||||
* SIP/TLS
|
||||
|
||||
low priority:
|
||||
-------------
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ fi
|
|||
|
||||
INTLTOOLIZE=$(which intltoolize)
|
||||
|
||||
#workaround for mingw bug in intltoolize script.
|
||||
if test "$INTLTOOLIZE" = "/bin/intltoolize" ; then
|
||||
INTLTOOLIZE=/usr/bin/intltoolize
|
||||
fi
|
||||
|
||||
echo "Generating build scripts in linphone..."
|
||||
set -x
|
||||
$LIBTOOLIZE --copy --force
|
||||
|
|
|
|||
|
|
@ -26,51 +26,53 @@ 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 \
|
||||
buffer.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 \
|
||||
lime.c \
|
||||
player.c
|
||||
localplayer.c
|
||||
lpconfig.c \
|
||||
message_storage.c \
|
||||
misc.c \
|
||||
offeranswer.c \
|
||||
player.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"
|
||||
|
|
@ -84,7 +86,8 @@ LOCAL_CFLAGS += \
|
|||
-DHAVE_CONFIG_H \
|
||||
-DLIBLINPHONE_VERSION=\"$(LIBLINPHONE_VERSION)\" \
|
||||
-DLINPHONE_PLUGINS_DIR=\"\\tmp\" \
|
||||
-DUSE_BELLESIP
|
||||
-DUSE_BELLESIP \
|
||||
-DHAVE_ZLIB
|
||||
|
||||
LOCAL_CFLAGS += -DIN_LINPHONE
|
||||
|
||||
|
|
@ -118,7 +121,7 @@ LOCAL_C_INCLUDES += \
|
|||
$(LOCAL_PATH)/../../externals/build/libxml2 \
|
||||
$(LOCAL_PATH)/../../externals/polarssl/include
|
||||
|
||||
LOCAL_LDLIBS += -llog -ldl
|
||||
LOCAL_LDLIBS += -llog -ldl -lz
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
cpufeatures \
|
||||
|
|
@ -218,16 +221,18 @@ LOCAL_CFLAGS += -DBUILD_UPNP
|
|||
LOCAL_SRC_FILES += upnp.c
|
||||
endif
|
||||
|
||||
LOCAL_STATIC_LIBRARIES += libspeex
|
||||
LOCAL_STATIC_LIBRARIES += libspeex
|
||||
|
||||
ifeq ($(BUILD_SRTP), 1)
|
||||
LOCAL_C_INCLUDES += $(SRTP_C_INCLUDE)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_ILBC), 1)
|
||||
ifneq ($(TARGET_ARCH_ABI),armeabi)
|
||||
LOCAL_CFLAGS += -DHAVE_ILBC=1
|
||||
LOCAL_STATIC_LIBRARIES += libmsilbc
|
||||
endif
|
||||
endif
|
||||
|
||||
LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += $(LIBLINPHONE_EXTENDED_STATIC_LIBS)
|
||||
|
|
@ -253,8 +258,8 @@ endif
|
|||
ifeq ($(BUILD_OPUS),1)
|
||||
LOCAL_STATIC_LIBRARIES += libopus
|
||||
endif
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||
LOCAL_EXPORT_CFLAGS := $(LOCAL_CFLAGS)
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||
LOCAL_EXPORT_CFLAGS := $(LOCAL_CFLAGS)
|
||||
|
||||
ifeq ($(_BUILD_VIDEO),1)
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ common_SRC_FILES := \
|
|||
log_collection_tester.c \
|
||||
transport_tester.c \
|
||||
player_tester.c \
|
||||
dtmf_tester.c
|
||||
dtmf_tester.c \
|
||||
accountmanager.c \
|
||||
offeranswer_tester.c \
|
||||
multicast_call_tester.c
|
||||
|
||||
common_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
|
|
@ -34,10 +37,10 @@ LOCAL_MODULE_FILENAME := liblinphone_tester-$(TARGET_ARCH_ABI)
|
|||
LOCAL_SRC_FILES += $(common_SRC_FILES)
|
||||
LOCAL_C_INCLUDES = $(common_C_INCLUDES)
|
||||
LOCAL_CFLAGS = -DIN_LINPHONE
|
||||
LOCAL_LDLIBS := -llog
|
||||
LOCAL_LDLIBS := -llog -lz
|
||||
|
||||
ifeq ($(BUILD_MATROSKA), 1)
|
||||
LOCAL_CFLAGS += -DHAVE_MATROSKA
|
||||
LOCAL_CFLAGS += -DHAVE_MATROSKA -DHAVE_ZLIB
|
||||
endif
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := cunit liblinphone
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
<string>Copyright 2011 Belledonne Communications</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.4</string>
|
||||
<key>NSAppSleepDisabled</key>
|
||||
<string>YES</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
export EXTRA_ARGS="--workdir $bundle_res"
|
||||
#export EXTRA_ARGS="--workdir $bundle_res"
|
||||
export LINPHONE_WORKDIR="$bundle_res"
|
||||
export GIO_EXTRA_MODULES="$bundle_lib/gio/modules"
|
||||
export PANGO_LIBDIR="$bundle_lib"
|
||||
export PANGO_SYSCONFDIR="$bundle_etc"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<prefix name="linphone">${env:LINPHONE_INSTALL_PREFIX}</prefix>
|
||||
<prefix name="ms2plugins">${env:MS2_PLUGINS_INSTALL_PREFIX}</prefix>
|
||||
<!-- This prefix definition is necessary if some dependencies are to be taken from /usr/local/lib -->
|
||||
<prefix name="local">/usr/local</prefix>
|
||||
<prefix name="local">${env:LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX}</prefix>
|
||||
<!-- The project directory is the default location of the created
|
||||
app. If you leave out the path, the current directory is
|
||||
used. Note the usage of an environment variable here again.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
<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;$(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>
|
||||
<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="\\linphone\\plugins";UNICODE;_XKEYCHECK_H;HAVE_ZLIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
|
|
@ -110,11 +110,13 @@
|
|||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_publish.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_registration.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_sdp.c" />
|
||||
<ClCompile Include="..\..\coreapi\buffer.c" />
|
||||
<ClCompile Include="..\..\coreapi\call_log.c" />
|
||||
<ClCompile Include="..\..\coreapi\call_params.c" />
|
||||
<ClCompile Include="..\..\coreapi\callbacks.c" />
|
||||
<ClCompile Include="..\..\coreapi\chat.c" />
|
||||
<ClCompile Include="..\..\coreapi\conference.c" />
|
||||
<ClCompile Include="..\..\coreapi\content.c" />
|
||||
<ClCompile Include="..\..\coreapi\ec-calibrator.c" />
|
||||
<ClCompile Include="..\..\coreapi\enum.c" />
|
||||
<ClCompile Include="..\..\coreapi\event.c" />
|
||||
|
|
@ -144,6 +146,8 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\coreapi\bellesip_sal\sal_impl.h" />
|
||||
<ClInclude Include="..\..\coreapi\buffer.h" />
|
||||
<ClInclude Include="..\..\coreapi\content.h" />
|
||||
<ClInclude Include="..\..\coreapi\enum.h" />
|
||||
<ClInclude Include="..\..\coreapi\event.h" />
|
||||
<ClInclude Include="..\..\coreapi\linphonecore.h" />
|
||||
|
|
@ -216,4 +220,4 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -30,4 +30,4 @@ namespace linphone_tester_native
|
|||
Platform::String^ testName(Platform::String^ suiteName, int testIndex);
|
||||
void run(Platform::String^ suiteName, Platform::String^ caseName, Platform::Boolean verbose);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
219
build/wp8/LibLinphone_no_tunnel.vcxproj
Normal file
219
build/wp8/LibLinphone_no_tunnel.vcxproj
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{08dd0d38-d9b5-4626-b60d-b4d76b571142}</ProjectGuid>
|
||||
<RootNamespace>LibLinphone</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\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;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="\\linphone\\plugins";UNICODE;_XKEYCHECK_H;HAVE_ZLIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<AdditionalDependencies>belle-sip_no_tunnel.lib;mediastreamer2.lib;ws2_32.lib;ortp.lib;gsm.lib;speex.lib;speexdsp.lib;libxml2.lib;sqlite.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary>
|
||||
</Link>
|
||||
<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;MSG_STORAGE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;MSG_STORAGE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\coreapi\address.c" />
|
||||
<ClCompile Include="..\..\coreapi\authentication.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_address_impl.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_impl.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_call.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_call_transfer.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_events.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_impl.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_info.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_message.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_presence.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_publish.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_registration.c" />
|
||||
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_sdp.c" />
|
||||
<ClCompile Include="..\..\coreapi\buffer.c" />
|
||||
<ClCompile Include="..\..\coreapi\call_log.c" />
|
||||
<ClCompile Include="..\..\coreapi\call_params.c" />
|
||||
<ClCompile Include="..\..\coreapi\callbacks.c" />
|
||||
<ClCompile Include="..\..\coreapi\chat.c" />
|
||||
<ClCompile Include="..\..\coreapi\conference.c" />
|
||||
<ClCompile Include="..\..\coreapi\content.c" />
|
||||
<ClCompile Include="..\..\coreapi\ec-calibrator.c" />
|
||||
<ClCompile Include="..\..\coreapi\enum.c" />
|
||||
<ClCompile Include="..\..\coreapi\event.c" />
|
||||
<ClCompile Include="..\..\coreapi\friend.c" />
|
||||
<ClCompile Include="..\..\coreapi\info.c" />
|
||||
<ClCompile Include="..\..\coreapi\linphonecall.c" />
|
||||
<ClCompile Include="..\..\coreapi\linphonecore.c" />
|
||||
<ClCompile Include="..\..\coreapi\linphone_tunnel_config.c" />
|
||||
<ClCompile Include="..\..\coreapi\linphone_tunnel_stubs.c" />
|
||||
<ClCompile Include="..\..\coreapi\localplayer.c" />
|
||||
<ClCompile Include="..\..\coreapi\lpconfig.c" />
|
||||
<ClCompile Include="..\..\coreapi\lsd.c" />
|
||||
<ClCompile Include="..\..\coreapi\message_storage.c" />
|
||||
<ClCompile Include="..\..\coreapi\misc.c" />
|
||||
<ClCompile Include="..\..\coreapi\offeranswer.c" />
|
||||
<ClCompile Include="..\..\coreapi\player.c" />
|
||||
<ClCompile Include="..\..\coreapi\presence.c" />
|
||||
<ClCompile Include="..\..\coreapi\proxy.c" />
|
||||
<ClCompile Include="..\..\coreapi\quality_reporting.c" />
|
||||
<ClCompile Include="..\..\coreapi\remote_provisioning.c" />
|
||||
<ClCompile Include="..\..\coreapi\sal.c" />
|
||||
<ClCompile Include="..\..\coreapi\siplogin.c" />
|
||||
<ClCompile Include="..\..\coreapi\sipsetup.c" />
|
||||
<ClCompile Include="..\..\coreapi\xml.c" />
|
||||
<ClCompile Include="..\..\coreapi\xml2lpc.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\coreapi\bellesip_sal\sal_impl.h" />
|
||||
<ClInclude Include="..\..\coreapi\buffer.h" />
|
||||
<ClInclude Include="..\..\coreapi\content.h" />
|
||||
<ClInclude Include="..\..\coreapi\enum.h" />
|
||||
<ClInclude Include="..\..\coreapi\event.h" />
|
||||
<ClInclude Include="..\..\coreapi\linphonecore.h" />
|
||||
<ClInclude Include="..\..\coreapi\linphonecore_utils.h" />
|
||||
<ClInclude Include="..\..\coreapi\linphonefriend.h" />
|
||||
<ClInclude Include="..\..\coreapi\linphone_tunnel.h" />
|
||||
<ClInclude Include="..\..\coreapi\lpconfig.h" />
|
||||
<ClInclude Include="..\..\coreapi\offeranswer.h" />
|
||||
<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">
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
</Reference>
|
||||
<Reference Include="platform.winmd">
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\bcg729\build\wp8\bcg729\bcg729.vcxproj">
|
||||
<Project>{1db09afe-fc9b-472e-a746-0e33f8ef8883}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\belle-sip\build\wp8\belle-sip\belle-sip_no_tunnel.vcxproj">
|
||||
<Project>{4c225a82-800b-427b-ba7b-61686a9b347f}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\msamr\build\wp8\msamr\msamr.vcxproj">
|
||||
<Project>{9924ac72-f96c-4e56-94d9-2b025da43c6b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\msilbc\build\wp8\msilbc\msilbc.vcxproj">
|
||||
<Project>{072fad20-7007-4da2-b2e7-16ce2b219f67}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\mssilk\build\wp8\mssilk\mssilk.vcxproj">
|
||||
<Project>{36b528f9-fb79-4078-a16b-0a7442581bb7}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\mswasapi\mswasapi\mswasapi.vcxproj">
|
||||
<Project>{d22bd217-d0f8-4274-9b3a-f3f35f46482c}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\mswebrtc\build\wp8\mswebrtc\mswebrtc.vcxproj">
|
||||
<Project>{b16b81a9-bef2-44c9-b603-1065183ae844}</Project>
|
||||
</ProjectReference>
|
||||
<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="..\..\mediastreamer2\build\wp8\mediastreamer2\mediastreamer2.vcxproj">
|
||||
<Project>{027bad0e-9179-48c1-9733-7aa7e2c2ec70}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\oRTP\build\wp8\oRTP\oRTP.vcxproj">
|
||||
<Project>{ffc7b532-0502-4d88-ac98-9e89071cbc97}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="libxml2\libxml2.vcxproj">
|
||||
<Project>{5dfa07b4-0be9-46a9-ba32-fdf5a55c580b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="zlib\zlib.vcxproj">
|
||||
<Project>{7afac3bb-d97b-4578-b9fe-5e1d2b94ea2f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
|
||||
</Project>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
############################################################################
|
||||
# FindLinphone.txt
|
||||
# FindLinphone.cmake
|
||||
# Copyright (C) 2014 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
|
|
@ -32,8 +32,11 @@ find_package(ORTP REQUIRED)
|
|||
find_package(MS2 REQUIRED)
|
||||
find_package(XML2 REQUIRED)
|
||||
find_package(BelleSIP REQUIRED)
|
||||
if(@ENABLE_MSG_STORAGE@)
|
||||
find_package(Sqlite3)
|
||||
endif()
|
||||
|
||||
set(_LINPHONEROOT_PATHS
|
||||
set(_LINPHONE_ROOT_PATHS
|
||||
${WITH_LINPHONE}
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
|
|
@ -56,6 +59,12 @@ find_library(LINPHONE_LIBRARIES
|
|||
|
||||
list(APPEND LINPHONE_INCLUDE_DIRS ${ORTP_INCLUDE_DIRS} ${MS2_INCLUDE_DIRS} ${XML2_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS})
|
||||
list(APPEND LINPHONE_LIBRARIES ${ORTP_LIBRARIES} ${MS2_LIBRARIES} ${XML2_LIBRARIES} ${BELLESIP_LIBRARIES})
|
||||
|
||||
if(SQLITE3_FOUND)
|
||||
list(APPEND LINPHONE_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIRS})
|
||||
list(APPEND LINPHONE_LIBRARIES ${SQLITE3_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND LINPHONE_LIBRARIES shlwapi)
|
||||
endif(WIN32)
|
||||
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 libnotify
|
||||
# NOTIFY_INCLUDE_DIRS - the libnotify include directory
|
||||
# NOTIFY_LIBRARIES - The libraries needed to use libnotify
|
||||
|
||||
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)
|
||||
63
cmake/FindSoup.cmake
Normal file
63
cmake/FindSoup.cmake
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
############################################################################
|
||||
# FindSoup.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 soup include file and library
|
||||
#
|
||||
# SOUP_FOUND - system has libsoup
|
||||
# SOUP_INCLUDE_DIRS - the libsoup include directory
|
||||
# SOUP_LIBRARIES - The libraries needed to use libsoup
|
||||
|
||||
find_package(GTK2 2.18 REQUIRED gtk)
|
||||
|
||||
set(_SOUP_ROOT_PATHS
|
||||
${WITH_SOUP}
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
|
||||
find_path(SOUP_INCLUDE_DIRS
|
||||
NAMES libsoup/soup.h
|
||||
HINTS _SOUP_ROOT_PATHS
|
||||
PATH_SUFFIXES include/libsoup-2.4
|
||||
)
|
||||
|
||||
if(SOUP_INCLUDE_DIRS)
|
||||
set(HAVE_LIBSOUP_SOUP_H 1)
|
||||
list(APPEND SOUP_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
find_library(SOUP_LIBRARIES
|
||||
NAMES soup-2.4
|
||||
HINTS ${_SOUP_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin lib
|
||||
)
|
||||
|
||||
if(SOUP_LIBRARIES)
|
||||
list(APPEND SOUP_LIBRARIES ${GTK2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Soup
|
||||
DEFAULT_MSG
|
||||
SOUP_INCLUDE_DIRS SOUP_LIBRARIES HAVE_LIBSOUP_SOUP_H
|
||||
)
|
||||
|
||||
mark_as_advanced(SOUP_INCLUDE_DIRS SOUP_LIBRARIES HAVE_LIBSOUP_SOUP_H)
|
||||
|
|
@ -26,7 +26,17 @@
|
|||
#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 BUILD_WIZARD
|
||||
#cmakedefine HAVE_NOTIFY4
|
||||
#cmakedefine HAVE_CU_GET_SUITE 1
|
||||
#cmakedefine HAVE_CU_CURSES 1
|
||||
82
configure.ac
82
configure.ac
|
|
@ -60,6 +60,9 @@ case $target in
|
|||
mingwce_found=yes
|
||||
;;
|
||||
*mingw*)
|
||||
dnl Workaround for mingw, whose compiler does not check in /usr/include ...
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/lib"
|
||||
CFLAGS="$CFLAGS -DORTP_STATIC -D_WIN32_WINNT=0x0501 "
|
||||
CXXFLAGS="$CXXFLAGS -DORTP_STATIC -D_WIN32_WINNT=0x0501"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
|
|
@ -76,7 +79,7 @@ case $target in
|
|||
x86_64-apple-darwin*|i686-apple-darwin*)
|
||||
MSPLUGINS_CFLAGS=""
|
||||
dnl use macport installation
|
||||
ACLOCAL_MACOS_FLAGS="-I /opt/local/share/aclocal"
|
||||
AS_IF([test -d "/opt/local/share/aclocal"], [ACLOCAL_MACOS_FLAGS="-I /opt/local/share/aclocal"])
|
||||
build_macos=yes
|
||||
;;
|
||||
|
||||
|
|
@ -129,7 +132,7 @@ AC_CONFIG_COMMANDS([libtool-hacking],
|
|||
|
||||
dnl Add the languages which your application supports here.
|
||||
PKG_PROG_PKG_CONFIG
|
||||
ALL_LINGUAS="fr it de ja es pl cs nl sv pt_BR hu ru zh_CN nb_NO zh_TW he sr"
|
||||
ALL_LINGUAS=$(cd po && echo *.po | sed 's/\.po//g')
|
||||
AC_SUBST(ALL_LINGUAS)
|
||||
AC_DEFINE_UNQUOTED(LINPHONE_ALL_LANGS, "$ALL_LINGUAS", [All supported languages])
|
||||
|
||||
|
|
@ -158,13 +161,16 @@ dnl AC_CHECK_LIB(intl,libintl_gettext)
|
|||
AC_CHECK_FUNCS([get_current_dir_name strndup stpcpy] )
|
||||
|
||||
AC_ARG_ENABLE(x11,
|
||||
[AS_HELP_STRING([--disable-x11], [Disable X11 support (default=no)])],
|
||||
[AS_HELP_STRING([--disable-x11], [Disable X11 support (default=yes for MacOSX, no otherwise)])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_x11=true ;;
|
||||
no) enable_x11=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-x11) ;;
|
||||
esac],
|
||||
[enable_x11=true]
|
||||
[case "$target_os" in
|
||||
*darwin*) enable_x11=false ;; #disable x11 on MacOS by default
|
||||
*) enable_x11=true ;;
|
||||
esac]
|
||||
)
|
||||
|
||||
dnl conditional build of LDAP support
|
||||
|
|
@ -268,6 +274,43 @@ if test "$build_upnp" != "false" ; then
|
|||
AC_DEFINE(BUILD_UPNP, 1, [Define if upnp enabled])
|
||||
fi
|
||||
|
||||
dnl check zlib
|
||||
AC_ARG_ENABLE(zlib,
|
||||
[AS_HELP_STRING([--disable-zlib], [Disable ZLib support])],
|
||||
[case "${enableval}" in
|
||||
yes) build_zlib=true ;;
|
||||
no) build_zlib=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-zlib) ;;
|
||||
esac],
|
||||
[build_zlib=auto]
|
||||
)
|
||||
if test "$build_zlib" != "false" ; then
|
||||
PKG_CHECK_MODULES(ZLIB, [zlib], [found_zlib=yes], [found_zlib=no])
|
||||
if test "x$found_zlib" = "xno" ; then
|
||||
AC_CHECK_LIB(z, inflate,
|
||||
[AC_CHECK_HEADER([zlib.h],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#include <zlib.h>
|
||||
#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1230)
|
||||
// compile error
|
||||
#endif
|
||||
]],[])],
|
||||
[found_zlib=yes])])])
|
||||
if test "x$found_zlib" = "xno" ; then
|
||||
AC_MSG_NOTICE([zlib library and headers not found])
|
||||
else
|
||||
AC_DEFINE( HAVE_ZLIB, 1, [ZLIB support] )
|
||||
ZLIB_LIBS='-lz'
|
||||
AC_SUBST(ZLIB_LIBS)
|
||||
fi
|
||||
else
|
||||
AC_MSG_NOTICE([ZLIB found])
|
||||
AC_DEFINE( HAVE_ZLIB, 1, [ZLIB support] )
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
dnl check libxml2
|
||||
PKG_CHECK_MODULES(LIBXML2, [libxml-2.0],[libxml2_found=yes],foo=bar)
|
||||
if test "$libxml2_found" != "yes" ; then
|
||||
|
|
@ -330,7 +373,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
|
||||
|
|
@ -586,6 +628,26 @@ AC_ARG_ENABLE(zrtp,
|
|||
[zrtp=false]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(dtls,
|
||||
[AS_HELP_STRING([--enable-dtls], [Turn on dtls support - requires polarssl > 1.4])],
|
||||
[case "${enableval}" in
|
||||
yes) dtls=true ;;
|
||||
no) dtls=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-dtls) ;;
|
||||
esac],
|
||||
[dtls=false]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(g729bCN,
|
||||
[AS_HELP_STRING([--enable-g729bCN], [Turn on or off usage of G729AnnexB in RFC3389 implementation of Comfort Noise Payload (default=no)])],
|
||||
[case "${enableval}" in
|
||||
yes) g729bCN=true ;;
|
||||
no) g729bCN=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-g729bCN) ;;
|
||||
esac],
|
||||
[g729bCN=false]
|
||||
)
|
||||
|
||||
dnl build console if required
|
||||
AM_CONDITIONAL(BUILD_CONSOLE, test x$console_ui = xtrue)
|
||||
|
||||
|
|
@ -596,6 +658,7 @@ dnl compilation of gtk user interface
|
|||
AM_CONDITIONAL(BUILD_GTK_UI, [test x$gtk_ui = xtrue ] )
|
||||
AM_CONDITIONAL(BUILD_WIN32, test x$mingw_found = xyes )
|
||||
AM_CONDITIONAL(BUILD_ZRTP, test x$zrtp = xtrue)
|
||||
AM_CONDITIONAL(BUILD_DTLS, test x$dtls = xtrue)
|
||||
|
||||
dnl check getenv
|
||||
AH_TEMPLATE([HAVE_GETENV])
|
||||
|
|
@ -756,7 +819,6 @@ AC_SUBST([MS2_VERSION])
|
|||
AC_SUBST([MS2_DIR])
|
||||
|
||||
|
||||
|
||||
AC_ARG_ENABLE(tunnel,
|
||||
[AS_HELP_STRING([--enable-tunnel=[yes/no]], [Turn on compilation of tunnel support (default=no)])],
|
||||
[case "${enableval}" in
|
||||
|
|
@ -782,8 +844,6 @@ AC_ARG_ENABLE(msg-storage,
|
|||
[enable_msg_storage=auto]
|
||||
)
|
||||
|
||||
AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue)
|
||||
|
||||
if test x$enable_msg_storage != xfalse; then
|
||||
PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no])
|
||||
if test "$found_sqlite" = "no"; then
|
||||
|
|
@ -792,6 +852,7 @@ if test x$enable_msg_storage != xfalse; then
|
|||
fi
|
||||
if test "$found_sqlite" = "yes"; then
|
||||
SQLITE3_CFLAGS+="-DMSG_STORAGE_ENABLED"
|
||||
enable_msg_storage=true
|
||||
else
|
||||
if test x$enable_msg_storage = xtrue; then
|
||||
AC_MSG_ERROR([sqlite3, required for message storage, not found])
|
||||
|
|
@ -803,7 +864,7 @@ if test x$enable_msg_storage != xfalse; then
|
|||
AC_SUBST(SQLITE3_LIBS)
|
||||
fi
|
||||
|
||||
|
||||
AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue)
|
||||
|
||||
PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.3.1])
|
||||
|
||||
|
|
@ -894,6 +955,7 @@ case "$target_os" in
|
|||
;;
|
||||
esac
|
||||
|
||||
|
||||
dnl ##################################################
|
||||
dnl # Check for doxygen
|
||||
dnl ##################################################
|
||||
|
|
@ -944,8 +1006,10 @@ printf "* %-30s %s\n" "Console interface" $console_ui
|
|||
printf "* %-30s %s\n" "Tools" $build_tools
|
||||
printf "* %-30s %s\n" "Message storage" $enable_msg_storage
|
||||
printf "* %-30s %s\n" "zRTP encryption" $zrtp
|
||||
printf "* %-30s %s\n" "DTLS encryption" $dtls
|
||||
printf "* %-30s %s\n" "uPnP support" $build_upnp
|
||||
printf "* %-30s %s\n" "LDAP support" $enable_ldap
|
||||
printf "* %-30s %s\n" "ZLIB support" $found_zlib
|
||||
|
||||
if test "$enable_tunnel" = "true" ; then
|
||||
printf "* %-30s %s\n" "Tunnel support" "true"
|
||||
|
|
|
|||
|
|
@ -150,6 +150,15 @@ static LPC_COMMAND commands[] = {
|
|||
"'help <command>'\t: displays specific help for command.\n"
|
||||
"'help advanced'\t: shows advanced commands.\n"
|
||||
},
|
||||
{ "answer", lpc_cmd_answer, "Answer a call",
|
||||
"'answer' : Answer the current incoming call\n"
|
||||
"'answer <call id>' : Answer the call with given id\n"
|
||||
},
|
||||
{ "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode",
|
||||
"'autoanswer' \t: show current autoanswer mode\n"
|
||||
"'autoanswer enable'\t: enable autoanswer mode\n"
|
||||
"'autoanswer disable'\t: disable autoanswer mode\n"
|
||||
},
|
||||
{ "call", lpc_cmd_call, "Call a SIP uri or number",
|
||||
#ifdef VIDEO_ENABLED
|
||||
"'call <sip-url or number> [options]' \t: initiate a call to the specified destination.\n"
|
||||
|
|
@ -162,83 +171,24 @@ static LPC_COMMAND commands[] = {
|
|||
},
|
||||
{ "calls", lpc_cmd_calls, "Show all the current calls with their id and status.",
|
||||
NULL
|
||||
},
|
||||
},
|
||||
{ "call-logs", lpc_cmd_call_logs, "Calls history", NULL
|
||||
},
|
||||
#ifdef VIDEO_ENABLED
|
||||
{ "camera", lpc_cmd_camera, "Send camera output for current call.",
|
||||
"'camera on'\t: allow sending of local camera video to remote end.\n"
|
||||
"'camera off'\t: disable sending of local camera's video to remote end.\n"
|
||||
},
|
||||
#endif
|
||||
{ "chat", lpc_cmd_chat, "Chat with a SIP uri",
|
||||
"'chat <sip-url> \"message\"' "
|
||||
": send a chat message \"message\" to the specified destination."
|
||||
},
|
||||
{ "terminate", lpc_cmd_terminate, "Terminate a call",
|
||||
"'terminate' : Terminate the current call\n"
|
||||
"'terminate <call id>' : Terminate the call with supplied id\n"
|
||||
"'terminate <all>' : Terminate all the current calls\n"
|
||||
},
|
||||
{ "answer", lpc_cmd_answer, "Answer a call",
|
||||
"'answer' : Answer the current incoming call\n"
|
||||
"'answer <call id>' : Answer the call with given id\n"
|
||||
},
|
||||
{ "pause", lpc_cmd_pause, "pause a call",
|
||||
"'pause' : pause the current call\n"},
|
||||
{ "resume", lpc_cmd_resume, "resume a call",
|
||||
"'resume' : resume the unique call\n"
|
||||
"'resume <call id>' : hold off the call with given id\n"},
|
||||
{ "transfer", lpc_cmd_transfer,
|
||||
"Transfer a call to a specified destination.",
|
||||
"'transfer <sip-uri>' : transfers the current active call to the destination sip-uri\n"
|
||||
"'transfer <call id> <sip-uri>': transfers the call with 'id' to the destination sip-uri\n"
|
||||
"'transfer <call id1> --to-call <call id2>': transfers the call with 'id1' to the destination of call 'id2' (attended transfer)\n"
|
||||
},
|
||||
{ "conference", lpc_cmd_conference, "Create and manage an audio conference.",
|
||||
"'conference add <call id> : join the call with id 'call id' into the audio conference."
|
||||
"'conference rm <call id> : remove the call with id 'call id' from the audio conference."
|
||||
},
|
||||
{ "mute", lpc_cmd_mute_mic,
|
||||
"Mute microphone and suspend voice transmission."},
|
||||
#ifdef VIDEO_ENABLED
|
||||
{ "camera", lpc_cmd_camera, "Send camera output for current call.",
|
||||
"'camera on'\t: allow sending of local camera video to remote end.\n"
|
||||
"'camera off'\t: disable sending of local camera's video to remote end.\n"},
|
||||
#endif
|
||||
{ "unmute", lpc_cmd_unmute_mic,
|
||||
"Unmute microphone and resume voice transmission."},
|
||||
{ "playbackgain", lpc_cmd_playback_gain,
|
||||
"Adjust playback gain."},
|
||||
{ "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL },
|
||||
|
||||
{ "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode",
|
||||
"'autoanswer' \t: show current autoanswer mode\n"
|
||||
"'autoanswer enable'\t: enable autoanswer mode\n"
|
||||
"'autoanswer disable'\t: disable autoanswer mode<64><65>\n"},
|
||||
{ "proxy", lpc_cmd_proxy, "Manage proxies",
|
||||
"'proxy list' : list all proxy setups.\n"
|
||||
"'proxy add' : add a new proxy setup.\n"
|
||||
"'proxy remove <index>' : remove proxy setup with number index.\n"
|
||||
"'proxy use <index>' : use proxy with number index as default proxy.\n"
|
||||
"'proxy unuse' : don't use a default proxy.\n"
|
||||
"'proxy show <index>' : show configuration and status of the proxy numbered by index.\n"
|
||||
"'proxy show default' : show configuration and status of the default proxy.\n"
|
||||
},
|
||||
{ "soundcard", lpc_cmd_soundcard, "Manage soundcards",
|
||||
"'soundcard list' : list all sound devices.\n"
|
||||
"'soundcard show' : show current sound devices configuration.\n"
|
||||
"'soundcard use <index>' : select a sound device.\n"
|
||||
"'soundcard use files' : use .wav files instead of soundcard\n"
|
||||
},
|
||||
{ "webcam", lpc_cmd_webcam, "Manage webcams",
|
||||
"'webcam list' : list all known devices.\n"
|
||||
"'webcam use <index>' : select a video device.\n"
|
||||
},
|
||||
{ "ipv6", lpc_cmd_ipv6, "Use IPV6",
|
||||
"'ipv6 status' : show ipv6 usage status.\n"
|
||||
"'ipv6 enable' : enable the use of the ipv6 network.\n"
|
||||
"'ipv6 disable' : do not use ipv6 network."
|
||||
},
|
||||
{ "nat", lpc_cmd_nat, "Set nat address",
|
||||
"'nat' : show nat settings.\n"
|
||||
"'nat <addr>' : set nat address.\n"
|
||||
},
|
||||
{ "stun", lpc_cmd_stun, "Set stun server address",
|
||||
"'stun' : show stun settings.\n"
|
||||
"'stun <addr>' : set stun server address.\n"
|
||||
{ "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL
|
||||
},
|
||||
{ "firewall", lpc_cmd_firewall, "Set firewall policy",
|
||||
"'firewall' : show current firewall policy.\n"
|
||||
|
|
@ -248,7 +198,6 @@ static LPC_COMMAND commands[] = {
|
|||
"'firewall ice' : use ice.\n"
|
||||
"'firewall upnp' : use uPnP IGD.\n"
|
||||
},
|
||||
{ "call-logs", lpc_cmd_call_logs, "Calls history", NULL },
|
||||
{ "friend", lpc_cmd_friend, "Manage friends",
|
||||
"'friend list [<pattern>]' : list friends.\n"
|
||||
"'friend call <index>' : call a friend.\n"
|
||||
|
|
@ -257,18 +206,79 @@ static LPC_COMMAND commands[] = {
|
|||
" there. Don't use '<' '>' around <addr>.\n"
|
||||
"'friend delete <index>' : remove friend, 'all' removes all\n"
|
||||
},
|
||||
{ "ipv6", lpc_cmd_ipv6, "Use IPV6",
|
||||
"'ipv6 status' : show ipv6 usage status.\n"
|
||||
"'ipv6 enable' : enable the use of the ipv6 network.\n"
|
||||
"'ipv6 disable' : do not use ipv6 network."
|
||||
},
|
||||
{ "mute", lpc_cmd_mute_mic,
|
||||
"Mute microphone and suspend voice transmission."
|
||||
},
|
||||
{ "nat", lpc_cmd_nat, "Set nat address",
|
||||
"'nat' : show nat settings.\n"
|
||||
"'nat <addr>' : set nat address.\n"
|
||||
},
|
||||
{ "pause", lpc_cmd_pause, "pause a call",
|
||||
"'pause' : pause the current call\n"
|
||||
},
|
||||
{ "play", lpc_cmd_play, "play a wav file",
|
||||
"This command has two roles:\n"
|
||||
"Plays a file instead of capturing from soundcard - only available in file mode (see 'help soundcard')\n"
|
||||
"Specifies a wav file to be played to play music to far end when putting it on hold (pause)\n"
|
||||
"'play <wav file>' : play a wav file."
|
||||
},
|
||||
{ "playbackgain", lpc_cmd_playback_gain,
|
||||
"Adjust playback gain."
|
||||
},
|
||||
{ "proxy", lpc_cmd_proxy, "Manage proxies",
|
||||
"'proxy list' : list all proxy setups.\n"
|
||||
"'proxy add' : add a new proxy setup.\n"
|
||||
"'proxy remove <index>' : remove proxy setup with number index.\n"
|
||||
"'proxy use <index>' : use proxy with number index as default proxy.\n"
|
||||
"'proxy unuse' : don't use a default proxy.\n"
|
||||
"'proxy show <index>' : show configuration and status of the proxy numbered by index.\n"
|
||||
"'proxy show default' : show configuration and status of the default proxy.\n"
|
||||
},
|
||||
{ "record", lpc_cmd_record, "record to a wav file",
|
||||
"This feature is available only in file mode (see 'help soundcard')\n"
|
||||
"'record <wav file>' : record into wav file."
|
||||
},
|
||||
{ "quit", lpc_cmd_quit, "Exit linphonec", NULL },
|
||||
{ (char *)NULL, (lpc_cmd_handler)NULL, (char *)NULL, (char *)NULL }
|
||||
{ "resume", lpc_cmd_resume, "resume a call",
|
||||
"'resume' : resume the unique call\n"
|
||||
"'resume <call id>' : hold off the call with given id\n"
|
||||
},
|
||||
{ "soundcard", lpc_cmd_soundcard, "Manage soundcards",
|
||||
"'soundcard list' : list all sound devices.\n"
|
||||
"'soundcard show' : show current sound devices configuration.\n"
|
||||
"'soundcard use <index>' : select a sound device.\n"
|
||||
"'soundcard use files' : use .wav files instead of soundcard\n"
|
||||
},
|
||||
{ "stun", lpc_cmd_stun, "Set stun server address",
|
||||
"'stun' : show stun settings.\n"
|
||||
"'stun <addr>' : set stun server address.\n"
|
||||
},
|
||||
{ "terminate", lpc_cmd_terminate, "Terminate a call",
|
||||
"'terminate' : Terminate the current call\n"
|
||||
"'terminate <call id>' : Terminate the call with supplied id\n"
|
||||
"'terminate <all>' : Terminate all the current calls\n"
|
||||
},
|
||||
{ "transfer", lpc_cmd_transfer,
|
||||
"Transfer a call to a specified destination.",
|
||||
"'transfer <sip-uri>' : transfers the current active call to the destination sip-uri\n"
|
||||
"'transfer <call id> <sip-uri>': transfers the call with 'id' to the destination sip-uri\n"
|
||||
"'transfer <call id1> --to-call <call id2>': transfers the call with 'id1' to the destination of call 'id2' (attended transfer)\n"
|
||||
},
|
||||
{ "unmute", lpc_cmd_unmute_mic,
|
||||
"Unmute microphone and resume voice transmission."
|
||||
},
|
||||
{ "webcam", lpc_cmd_webcam, "Manage webcams",
|
||||
"'webcam list' : list all known devices.\n"
|
||||
"'webcam use <index>' : select a video device.\n"
|
||||
},
|
||||
{ "quit", lpc_cmd_quit, "Exit linphonec", NULL
|
||||
},
|
||||
{ (char *)NULL, (lpc_cmd_handler)NULL, (char *)NULL, (char *)NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -292,7 +302,8 @@ static LPC_COMMAND advanced_commands[] = {
|
|||
{ "nortp-on-audio-mute", lpc_cmd_rtp_no_xmit_on_audio_mute,
|
||||
"Set the rtp_no_xmit_on_audio_mute configuration parameter",
|
||||
" If set to 1 then rtp transmission will be muted when\n"
|
||||
" audio is muted , otherwise rtp is always sent."},
|
||||
" audio is muted , otherwise rtp is always sent."
|
||||
},
|
||||
#ifdef VIDEO_ENABLED
|
||||
{ "vwindow", lpc_cmd_video_window, "Control video display window",
|
||||
"'vwindow show': shows video window\n"
|
||||
|
|
@ -316,14 +327,16 @@ static LPC_COMMAND advanced_commands[] = {
|
|||
{ "preview-snapshot", lpc_cmd_preview_snapshot, "Take a snapshot of currently captured video stream",
|
||||
"'preview-snapshot <file path>': take a snapshot and records it in jpeg format into the supplied path\n"
|
||||
},
|
||||
{ "vfureq", lpc_cmd_vfureq, "Request the other side to send VFU for the current call"},
|
||||
{ "vfureq", lpc_cmd_vfureq, "Request the other side to send VFU for the current call"
|
||||
},
|
||||
#endif
|
||||
{ "states", lpc_cmd_states, "Show internal states of liblinphone, registrations and calls, according to linphonecore.h definitions",
|
||||
"'states global': shows global state of liblinphone \n"
|
||||
"'states calls': shows state of calls\n"
|
||||
"'states proxies': shows state of proxy configurations"
|
||||
},
|
||||
{ "register", lpc_cmd_register, "Register in one line to a proxy" , "register <sip identity> <sip proxy> <password>"},
|
||||
{ "register", lpc_cmd_register, "Register in one line to a proxy" , "register <sip identity> <sip proxy> <password>"
|
||||
},
|
||||
{ "unregister", lpc_cmd_unregister, "Unregister from default proxy", NULL },
|
||||
{ "status", lpc_cmd_status, "Print various status information",
|
||||
"'status register' \t: print status concerning registration\n"
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ static int trace_level = 0;
|
|||
static char *logfile_name = NULL;
|
||||
static char configfile_name[PATH_MAX];
|
||||
static char zrtpsecrets[PATH_MAX];
|
||||
static char usr_certificates_path[PATH_MAX];
|
||||
static const char *factory_configfile_name=NULL;
|
||||
static char *sip_addr_to_call = NULL; /* for autocall */
|
||||
static int window_id = 0; /* 0=standalone window, or window id for embedding video */
|
||||
|
|
@ -535,7 +536,7 @@ char *linphonec_readline(char *prompt){
|
|||
fprintf(stdout,"%s",prompt);
|
||||
fflush(stdout);
|
||||
while(1){
|
||||
|
||||
|
||||
ms_mutex_lock(&prompt_mutex);
|
||||
if (have_prompt){
|
||||
char *ret=strdup(received_prompt);
|
||||
|
|
@ -680,6 +681,8 @@ linphonec_init(int argc, char **argv)
|
|||
getenv("HOME"));
|
||||
snprintf(zrtpsecrets, PATH_MAX, "%s/.linphone-zidcache",
|
||||
getenv("HOME"));
|
||||
snprintf(usr_certificates_path, PATH_MAX, "%s/.linphone-usr-crt",
|
||||
getenv("HOME"));
|
||||
#elif defined(_WIN32_WCE)
|
||||
strncpy(configfile_name,PACKAGE_DIR "\\linphonerc",PATH_MAX);
|
||||
mylogfile=fopen(PACKAGE_DIR "\\" "linphonec.log","w");
|
||||
|
|
@ -689,6 +692,8 @@ linphonec_init(int argc, char **argv)
|
|||
getenv("APPDATA"));
|
||||
snprintf(zrtpsecrets, PATH_MAX, "%s/Linphone/linphone-zidcache",
|
||||
getenv("APPDATA"));
|
||||
snprintf(usr_certificates_path, PATH_MAX, "%s/Linphone/linphone-usr-crt",
|
||||
getenv("APPDATA"));
|
||||
#endif
|
||||
/* Handle configuration filename changes */
|
||||
switch (handle_configfile_migration())
|
||||
|
|
@ -745,6 +750,7 @@ linphonec_init(int argc, char **argv)
|
|||
|
||||
linphone_core_set_user_agent(linphonec,"Linphonec", LINPHONE_VERSION);
|
||||
linphone_core_set_zrtp_secrets_file(linphonec,zrtpsecrets);
|
||||
linphone_core_set_user_certificates_path(linphonec,usr_certificates_path);
|
||||
linphone_core_enable_video_capture(linphonec, vcap_enabled);
|
||||
linphone_core_enable_video_display(linphonec, display_enabled);
|
||||
if (display_enabled && window_id != 0)
|
||||
|
|
@ -925,7 +931,8 @@ print_usage (int exit_status)
|
|||
" -D enable video display only (disabled by default)\n"
|
||||
" -S show general state messages (disabled by default)\n"
|
||||
" --wid windowid force embedding of video window into provided windowid (disabled by default)\n"
|
||||
" -v or --version display version and exits.\n");
|
||||
" -v or --version display version and exits.\n"
|
||||
);
|
||||
|
||||
exit(exit_status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <ws2tcpip.h>
|
||||
|
|
@ -125,11 +126,36 @@ static void print_usage(void){
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
static char *argv_to_line(int argc, char *argv[]) {
|
||||
int i;
|
||||
int line_length;
|
||||
char *line;
|
||||
|
||||
assert( argc>=0 );
|
||||
|
||||
if(argc == 0) return NULL;
|
||||
|
||||
line_length = strlen(argv[0]);
|
||||
for(i=1; i<argc; i++) {
|
||||
line_length += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
line = ortp_malloc0((line_length +1) * sizeof(char));
|
||||
strcat(line, argv[0]);
|
||||
for(i=1; i<argc; i++) {
|
||||
strcat(line, " ");
|
||||
strcat(line, argv[i]);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_ARGS 10
|
||||
|
||||
#ifndef WIN32
|
||||
static void spawn_linphonec(int argc, char *argv[]){
|
||||
char * args[10];
|
||||
char * args[MAX_ARGS];
|
||||
int i,j;
|
||||
pid_t pid;
|
||||
j=0;
|
||||
|
|
@ -178,13 +204,21 @@ static void spawn_linphonec(int argc, char *argv[]){
|
|||
PROCESS_INFORMATION pinfo;
|
||||
STARTUPINFO si;
|
||||
BOOL ret;
|
||||
const char *cmd = "linphoned.exe --pipe -c NUL";
|
||||
char *args_in_line = argv_to_line(argc, argv);
|
||||
char *cmd_with_args;
|
||||
|
||||
ZeroMemory( &si, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory( &pinfo, sizeof(pinfo) );
|
||||
|
||||
|
||||
ret=CreateProcess(NULL,"linphoned.exe --pipe -c NUL",
|
||||
if(args_in_line) {
|
||||
cmd_with_args = ortp_strdup_printf("%s %s", cmd, args_in_line);
|
||||
} else {
|
||||
cmd_with_args = ortp_strdup(cmd);
|
||||
}
|
||||
|
||||
ret=CreateProcess(NULL, cmd_with_args,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
|
|
@ -193,8 +227,12 @@ static void spawn_linphonec(int argc, char *argv[]){
|
|||
NULL,
|
||||
&si,
|
||||
&pinfo);
|
||||
|
||||
if(args_in_line) ortp_free(args_in_line);
|
||||
ortp_free(cmd_with_args);
|
||||
|
||||
if (!ret){
|
||||
fprintf(stderr,"Spawning of linphonec.exe failed.\n");
|
||||
fprintf(stderr,"Spawning of linphoned.exe failed.\n");
|
||||
}else{
|
||||
WaitForInputIdle(pinfo.hProcess,1000);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -41,46 +42,51 @@ set(SOURCE_FILES
|
|||
bellesip_sal/sal_op_publish.c
|
||||
bellesip_sal/sal_op_registration.c
|
||||
bellesip_sal/sal_sdp.c
|
||||
buffer.c
|
||||
callbacks.c
|
||||
call_log.c
|
||||
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
|
||||
|
|
@ -91,6 +97,9 @@ if(ENABLE_TUNNEL)
|
|||
else()
|
||||
list(APPEND SOURCE_FILES linphone_tunnel_stubs.c)
|
||||
endif()
|
||||
if(ENABLE_ASSISTANT)
|
||||
list(APPEND SOURCE_FILES sipwizard.c)
|
||||
endif()
|
||||
|
||||
set(GENERATED_SOURCE_FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h
|
||||
|
|
@ -101,15 +110,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}
|
||||
|
|
@ -117,9 +121,15 @@ set(LIBS
|
|||
${MS2_LIBRARIES}
|
||||
${XML2_LIBRARIES}
|
||||
)
|
||||
if(SQLITE3_FOUND)
|
||||
list(APPEND LIBS ${SQLITE3_LIBRARIES})
|
||||
endif()
|
||||
if(ENABLE_TUNNEL)
|
||||
list(APPEND LIBS ${TUNNEL_LIBRARIES})
|
||||
endif()
|
||||
if(ENABLE_ASSISTANT)
|
||||
list(APPEND LIBS ${SOUP_LIBRARIES})
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND LIBS shlwapi)
|
||||
endif()
|
||||
|
|
@ -129,7 +139,7 @@ if(ENABLE_STATIC)
|
|||
target_link_libraries(linphone ${LIBS})
|
||||
else()
|
||||
add_library(linphone SHARED ${SOURCE_FILES} ${GENERATED_SOURCE_FILES})
|
||||
set_target_properties(linphone PROPERTIES VERSION ${LINPHONE_VERSION} SOVERSION ${LINPHONE_SO_VERSION} LINKER_LANGUAGE CXX)
|
||||
set_target_properties(linphone PROPERTIES VERSION ${LINPHONE_SO_VERSION} LINKER_LANGUAGE CXX)
|
||||
target_link_libraries(linphone ${LIBS})
|
||||
if(MSVC)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
|
@ -150,8 +160,10 @@ install(TARGETS linphone
|
|||
|
||||
|
||||
set(HEADER_FILES
|
||||
buffer.h
|
||||
call_log.h
|
||||
call_params.h
|
||||
content.h
|
||||
event.h
|
||||
linphonecore.h
|
||||
linphonecore_utils.h
|
||||
|
|
|
|||
|
|
@ -24,46 +24,64 @@ 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=\
|
||||
buffer.h \
|
||||
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 \
|
||||
lime.c \
|
||||
quality_reporting.c quality_reporting.h\
|
||||
buffer.c \
|
||||
callbacks.c \
|
||||
call_log.c \
|
||||
call_params.c \
|
||||
player.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 \
|
||||
lime.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 quality_reporting.h\
|
||||
remote_provisioning.c \
|
||||
sal.c \
|
||||
siplogin.c \
|
||||
sipsetup.c sipsetup.h \
|
||||
xml2lpc.c \
|
||||
xml.c \
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
if BUILD_UPNP
|
||||
|
|
@ -114,14 +132,16 @@ endif
|
|||
endif
|
||||
|
||||
liblinphone_la_LIBADD= \
|
||||
$(SIPSTACK_LIBS) \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) $(OPENSSL_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SIPSTACK_LIBS) \
|
||||
$(TUNNEL_LIBS) \
|
||||
$(LIBSOUP_LIBS) \
|
||||
$(SQLITE3_LIBS) \
|
||||
$(LIBXML2_LIBS) \
|
||||
$(LDAP_LIBS) $(SASL_LIBS)
|
||||
$(LDAP_LIBS) \
|
||||
$(SASL_LIBS) \
|
||||
$(ZLIB_LIBS)
|
||||
|
||||
|
||||
if ENABLE_TESTS
|
||||
|
|
@ -141,13 +161,13 @@ test_numbers_LDADD=liblinphone.la $(liblinphone_la_LIBADD)
|
|||
endif
|
||||
|
||||
AM_CPPFLAGS=\
|
||||
-I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir)
|
||||
-I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(MEDIASTREAMER_CFLAGS)
|
||||
|
||||
COMMON_CFLAGS=\
|
||||
$(STRICT_OPTIONS) \
|
||||
-DIN_LINPHONE \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(SIPSTACK_CFLAGS) \
|
||||
$(LIBSOUP_CFLAGS) \
|
||||
-DENABLE_TRACE \
|
||||
|
|
@ -158,7 +178,9 @@ COMMON_CFLAGS=\
|
|||
$(TUNNEL_CFLAGS) \
|
||||
$(SQLITE3_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS) \
|
||||
$(LDAP_CFLAGS) $(SASL_CFLAGS)
|
||||
$(LDAP_CFLAGS) \
|
||||
$(SASL_CFLAGS) \
|
||||
$(ZLIB_CFLAGS)
|
||||
|
||||
if BUILD_WIZARD
|
||||
COMMON_CFLAGS+= -DBUILD_WIZARD
|
||||
|
|
@ -186,15 +208,13 @@ make_gitversion_h:
|
|||
else \
|
||||
$(ECHO) -n "" > $(builddir)/$(GITVERSION_FILE_TMP) ; \
|
||||
fi ; \
|
||||
else \
|
||||
$(ECHO) -n "" > $(builddir)/$(GITVERSION_FILE_TMP) ; \
|
||||
if ! test -f $(builddir)/$(GITVERSION_FILE) ; then \
|
||||
cp -f $(builddir)/$(GITVERSION_FILE_TMP) $(builddir)/$(GITVERSION_FILE) ; \
|
||||
fi ; \
|
||||
if test "`cat $(builddir)/$(GITVERSION_FILE_TMP)`" != "`cat $(builddir)/$(GITVERSION_FILE)`" ; then \
|
||||
cp -f $(builddir)/$(GITVERSION_FILE_TMP) $(builddir)/$(GITVERSION_FILE) ; \
|
||||
fi ; \
|
||||
rm -f $(builddir)/$(GITVERSION_FILE_TMP) ; \
|
||||
fi
|
||||
if ! test -f $(builddir)/$(GITVERSION_FILE) ; then \
|
||||
cp -f $(builddir)/$(GITVERSION_FILE_TMP) $(builddir)/$(GITVERSION_FILE) ; \
|
||||
fi
|
||||
if test "`cat $(builddir)/$(GITVERSION_FILE_TMP)`" != "`cat $(builddir)/$(GITVERSION_FILE)`" ; then \
|
||||
cp -f $(builddir)/$(GITVERSION_FILE_TMP) $(builddir)/$(GITVERSION_FILE) ; \
|
||||
fi
|
||||
rm -f $(builddir)/$(GITVERSION_FILE_TMP) ;
|
||||
|
||||
$(GITVERSION_FILE): make_gitversion_h
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
#include "ortp/rtpsession.h"
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
#ifndef USE_BELLESIP
|
||||
#include "eXosip2/eXosip_transport_hook.h"
|
||||
#endif
|
||||
#include "private.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
|
|
@ -97,7 +94,7 @@ RtpTransport *TunnelManager::createRtpTransport(int port){
|
|||
|
||||
void TunnelManager::startClient() {
|
||||
ms_message("TunnelManager: Starting tunnel client");
|
||||
mTunnelClient = new TunnelClient();
|
||||
mTunnelClient = new TunnelClient(TRUE);
|
||||
mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this);
|
||||
list<ServerAddr>::iterator it;
|
||||
for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){
|
||||
|
|
@ -122,18 +119,16 @@ int TunnelManager::customSendto(struct _RtpTransport *t, mblk_t *msg , int flags
|
|||
}
|
||||
|
||||
int TunnelManager::customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen){
|
||||
memset(&msg->recv_addr,0,sizeof(msg->recv_addr));
|
||||
int err=((TunnelSocket*)t->data)->recvfrom(msg->b_wptr,msg->b_datap->db_lim-msg->b_datap->db_base,from,*fromlen);
|
||||
//to make ice happy
|
||||
inet_aton(((TunnelManager*)((TunnelSocket*)t->data)->getUserPointer())->mLocalAddr,&msg->recv_addr.addr.ipi_addr);
|
||||
if (err>0) return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TunnelManager::TunnelManager(LinphoneCore* lc) :
|
||||
mCore(lc),
|
||||
#ifndef USE_BELLESIP
|
||||
mSipSocket(NULL),
|
||||
mExosipTransport(NULL),
|
||||
#endif
|
||||
mMode(LinphoneTunnelModeDisable),
|
||||
mState(disabled),
|
||||
mTunnelizeSipPackets(true),
|
||||
|
|
@ -153,6 +148,7 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :
|
|||
mVTable = linphone_core_v_table_new();
|
||||
mVTable->network_reachable = networkReachableCb;
|
||||
linphone_core_add_listener(mCore, mVTable);
|
||||
linphone_core_get_local_ip_for(AF_INET, NULL, mLocalAddr);
|
||||
}
|
||||
|
||||
TunnelManager::~TunnelManager(){
|
||||
|
|
@ -206,8 +202,8 @@ void TunnelManager::setMode(LinphoneTunnelMode mode) {
|
|||
return;
|
||||
}
|
||||
ms_message("TunnelManager: switching mode from %s to %s",
|
||||
tunnel_mode_to_string(mMode),
|
||||
tunnel_mode_to_string(mode));
|
||||
linphone_tunnel_mode_to_string(mMode),
|
||||
linphone_tunnel_mode_to_string(mode));
|
||||
switch(mode) {
|
||||
case LinphoneTunnelModeEnable:
|
||||
if(mState == disabled) {
|
||||
|
|
@ -371,6 +367,7 @@ void TunnelManager::networkReachableCb(LinphoneCore *lc, bool_t reachable) {
|
|||
tunnel->startAutoDetection();
|
||||
tunnel->mState = autodetecting;
|
||||
}
|
||||
linphone_core_get_local_ip_for(AF_INET, NULL,tunnel->mLocalAddr);
|
||||
}
|
||||
|
||||
bool TunnelManager::startAutoDetection() {
|
||||
|
|
@ -388,7 +385,7 @@ bool TunnelManager::startAutoDetection() {
|
|||
bool TunnelManager::isActivated() const{
|
||||
switch(getMode()){
|
||||
case LinphoneTunnelModeAuto:
|
||||
return !mState==disabled;
|
||||
return !(mState==disabled);
|
||||
case LinphoneTunnelModeDisable:
|
||||
return false;
|
||||
case LinphoneTunnelModeEnable:
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ namespace belledonnecomm {
|
|||
LinphoneRtpTransportFactories mTransportFactories;
|
||||
Mutex mMutex;
|
||||
std::queue<Event> mEvq;
|
||||
char mLocalAddr[64];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -154,11 +154,34 @@ char *linphone_address_as_string_uri_only(const LinphoneAddress *u){
|
|||
|
||||
/**
|
||||
* Returns true if address refers to a secure location (sips)
|
||||
* @deprecated use linphone_address_get_secure()
|
||||
**/
|
||||
bool_t linphone_address_is_secure(const LinphoneAddress *uri){
|
||||
return sal_address_is_secure(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if address refers to a secure location (sips)
|
||||
**/
|
||||
bool_t linphone_address_get_secure(const LinphoneAddress *uri){
|
||||
return sal_address_is_secure(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the address refer to a secure location (sips scheme)
|
||||
* @param enabled TRUE if address is requested to be secure.
|
||||
**/
|
||||
void linphone_address_set_secure(LinphoneAddress *addr, bool_t enabled){
|
||||
sal_address_set_secure(addr, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if address is a routable sip address
|
||||
*/
|
||||
bool_t linphone_address_is_sip(const LinphoneAddress *uri){
|
||||
return sal_address_is_sip(uri);
|
||||
}
|
||||
|
||||
static bool_t strings_equals(const char *s1, const char *s2){
|
||||
if (s1==NULL && s2==NULL) return TRUE;
|
||||
if (s1!=NULL && s2!=NULL && strcmp(s1,s2)==0) return TRUE;
|
||||
|
|
@ -167,7 +190,10 @@ static bool_t strings_equals(const char *s1, const char *s2){
|
|||
|
||||
/**
|
||||
* Compare two LinphoneAddress ignoring tags and headers, basically just domain, username, and port.
|
||||
* Returns TRUE if they are equal.
|
||||
* @param[in] a1 LinphoneAddress object
|
||||
* @param[in] a2 LinphoneAddress object
|
||||
* @return Boolean value telling if the LinphoneAddress objects are equal.
|
||||
* @see linphone_address_equal()
|
||||
**/
|
||||
bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2){
|
||||
const char *u1,*u2;
|
||||
|
|
@ -182,6 +208,27 @@ bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddr
|
|||
return strings_equals(u1,u2) && strings_equals(h1,h2) && p1==p2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two LinphoneAddress taking the tags and headers into account.
|
||||
* @param[in] a1 LinphoneAddress object
|
||||
* @param[in] a2 LinphoneAddress object
|
||||
* @return Boolean value telling if the LinphoneAddress objects are equal.
|
||||
* @see linphone_address_weak_equal()
|
||||
*/
|
||||
bool_t linphone_address_equal(const LinphoneAddress *a1, const LinphoneAddress *a2) {
|
||||
char *s1;
|
||||
char *s2;
|
||||
bool_t res;
|
||||
if ((a1 == NULL) && (a2 == NULL)) return TRUE;
|
||||
if ((a1 == NULL) || (a2 == NULL)) return FALSE;
|
||||
s1 = linphone_address_as_string(a1);
|
||||
s2 = linphone_address_as_string(a2);
|
||||
res = (strcmp(s1, s2) == 0) ? TRUE : FALSE;
|
||||
ms_free(s1);
|
||||
ms_free(s2);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a LinphoneAddress object (actually calls linphone_address_unref()).
|
||||
* @deprecated Use linphone_address_unref() instead
|
||||
|
|
@ -201,6 +248,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ static char * remove_quotes(char * input){
|
|||
return input;
|
||||
}
|
||||
|
||||
static int realm_match(const char *realm1, const char *realm2){
|
||||
static bool_t realm_match(const char *realm1, const char *realm2){
|
||||
if (realm1==NULL && realm2==NULL) return TRUE;
|
||||
if (realm1!=NULL && realm2!=NULL){
|
||||
if (strcmp(realm1,realm2)==0) return TRUE;
|
||||
|
|
@ -226,7 +226,7 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
|
|||
LinphoneAuthInfo *pinfo = (LinphoneAuthInfo*)elem->data;
|
||||
if (username && pinfo->username && strcmp(username,pinfo->username)==0) {
|
||||
if (realm && domain){
|
||||
if (pinfo->realm && strcmp(realm,pinfo->realm)==0
|
||||
if (pinfo->realm && realm_match(realm,pinfo->realm)
|
||||
&& pinfo->domain && strcmp(domain,pinfo->domain)==0) {
|
||||
return pinfo;
|
||||
}
|
||||
|
|
@ -238,9 +238,9 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
|
|||
}
|
||||
ret=pinfo;
|
||||
}
|
||||
} else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0) {
|
||||
} else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0 && pinfo->ha1==NULL) {
|
||||
return pinfo;
|
||||
} else if (!domain) {
|
||||
} else if (!domain && pinfo->ha1==NULL) {
|
||||
return pinfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -271,6 +271,7 @@ const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const cha
|
|||
if (ai==NULL){
|
||||
ai=find_auth_info(lc,username,NULL,NULL);
|
||||
}
|
||||
/*if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", ai->username, ai->realm);*/
|
||||
return ai;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,13 +39,22 @@ 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;
|
||||
}
|
||||
|
||||
void sal_address_set_secure(SalAddress *addr, bool_t enabled){
|
||||
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);
|
||||
if (uri) belle_sip_uri_set_secure(uri,enabled);
|
||||
}
|
||||
|
||||
bool_t sal_address_is_secure(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);
|
||||
|
|
@ -114,6 +123,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);
|
||||
}
|
||||
|
|
@ -140,12 +157,28 @@ char *sal_address_as_string(const SalAddress *addr){
|
|||
return ms_strdup(tmp);
|
||||
}
|
||||
|
||||
bool_t sal_address_is_sip(const SalAddress *addr){
|
||||
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
|
||||
return belle_sip_header_address_get_uri(header_addr) != NULL;
|
||||
}
|
||||
|
||||
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 +199,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));
|
||||
|
|
@ -184,7 +221,7 @@ void sal_address_unref(SalAddress *addr){
|
|||
belle_sip_object_unref(BELLE_SIP_HEADER_ADDRESS(addr));
|
||||
}
|
||||
|
||||
bool_t sal_address_is_ipv6(SalAddress *addr){
|
||||
bool_t sal_address_is_ipv6(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);
|
||||
if (uri){
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1060,10 +1073,53 @@ void sal_signing_key_parse_file(SalAuthInfo* auth_info, const char* path, const
|
|||
if (auth_info->key) belle_sip_object_ref((belle_sip_object_t *) auth_info->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a directory to get a certificate with the given subject common name
|
||||
*
|
||||
*/
|
||||
void sal_certificates_chain_parse_directory(char **certificate_pem, char **key_pem, char **fingerprint, const char* path, const char *subject, SalCertificateRawFormat format, bool_t generate_certificate, bool_t generate_dtls_fingerprint) {
|
||||
belle_sip_certificates_chain_t *certificate = NULL;
|
||||
belle_sip_signing_key_t *key = NULL;
|
||||
*certificate_pem = NULL;
|
||||
*key_pem = NULL;
|
||||
if (belle_sip_get_certificate_and_pkey_in_dir(path, subject, &certificate, &key, (belle_sip_certificate_raw_format_t)format) == 0) {
|
||||
*certificate_pem = belle_sip_certificates_chain_get_pem(certificate);
|
||||
*key_pem = belle_sip_signing_key_get_pem(key);
|
||||
ms_message("Retrieve certificate with CN=%s successful\n", subject);
|
||||
} else {
|
||||
if (generate_certificate == TRUE) {
|
||||
if ( belle_sip_generate_self_signed_certificate(path, subject, &certificate, &key) == 0) {
|
||||
*certificate_pem = belle_sip_certificates_chain_get_pem(certificate);
|
||||
*key_pem = belle_sip_signing_key_get_pem(key);
|
||||
ms_message("Generate self-signed certificate with CN=%s successful\n", subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* generate the fingerprint as described in RFC4572 if needed */
|
||||
if ((generate_dtls_fingerprint == TRUE) && (fingerprint != NULL)) {
|
||||
if (*fingerprint != NULL) {
|
||||
ms_free(*fingerprint);
|
||||
}
|
||||
*fingerprint = belle_sip_certificates_chain_get_fingerprint(certificate);
|
||||
}
|
||||
|
||||
/* free key and certificate */
|
||||
if ( certificate != NULL ) {
|
||||
belle_sip_object_unref(certificate);
|
||||
}
|
||||
if ( key != NULL ) {
|
||||
belle_sip_object_unref(key);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -1079,11 +1135,21 @@ void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer) {
|
|||
belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(sal->stack);
|
||||
belle_sip_main_loop_remove_source(ml, timer);
|
||||
}
|
||||
|
||||
unsigned long sal_begin_background_task(const char *name, void (*max_time_reached)(void *), void *data){
|
||||
return belle_sip_begin_background_task(name, max_time_reached, data);
|
||||
}
|
||||
|
||||
void sal_end_background_task(unsigned long id){
|
||||
belle_sip_end_background_task(id);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
void sal_default_set_sdp_handling(Sal *sal, SalOpSDPHandling sdp_handling_method) {
|
||||
if (sdp_handling_method != SalOpSDPNormal ) ms_message("Enabling special SDP handling for all new SalOp in Sal[%p]!", sal);
|
||||
sal->default_sdp_handling = sdp_handling_method;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "belle-sip/belle-sip.h"
|
||||
#include "belle-sip/belle-sdp.h"
|
||||
|
||||
|
||||
|
||||
struct Sal{
|
||||
SalCallbacks callbacks;
|
||||
MSList *pending_auths;/*MSList of SalOp */
|
||||
|
|
@ -52,7 +50,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;
|
||||
SalOpSDPHandling default_sdp_handling;
|
||||
};
|
||||
|
||||
typedef enum SalOpState {
|
||||
|
|
@ -107,7 +105,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 */
|
||||
SalOpSDPHandling sdp_handling;
|
||||
int auth_requests; /*number of auth requested for this op*/
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -62,16 +62,19 @@ static void sdp_process(SalOp *h){
|
|||
strcpy(h->result->addr,h->base.remote_media->addr);
|
||||
h->result->bandwidth=h->base.remote_media->bandwidth;
|
||||
|
||||
for(i=0;i<sal_media_description_get_nb_active_streams(h->result);++i){
|
||||
strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
|
||||
h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
|
||||
h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
|
||||
h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
|
||||
strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
|
||||
h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
|
||||
for(i=0;i<h->result->nb_streams;++i){
|
||||
/*copy back parameters from remote description that we need in our result description*/
|
||||
if (h->result->streams[i].rtp_port!=0){ /*if stream was accepted*/
|
||||
strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
|
||||
h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
|
||||
h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
|
||||
h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
|
||||
strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
|
||||
h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
|
||||
|
||||
if ((h->result->streams[i].proto == SalProtoRtpSavpf) || (h->result->streams[i].proto == SalProtoRtpSavp)) {
|
||||
h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
|
||||
if ((h->result->streams[i].proto == SalProtoRtpSavpf) || (h->result->streams[i].proto == SalProtoRtpSavp)) {
|
||||
h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -91,9 +94,10 @@ static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* ses
|
|||
|
||||
/* 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);
|
||||
error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length);
|
||||
if( error != BELLE_SIP_OK ){
|
||||
bufLen *= 2;
|
||||
length = 0;
|
||||
buff = belle_sip_realloc(buff,bufLen);
|
||||
}
|
||||
}
|
||||
|
|
@ -213,7 +217,8 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
dialog_state=dialog ? belle_sip_dialog_get_state(dialog) : BELLE_SIP_DIALOG_NULL;
|
||||
method=belle_sip_request_get_method(req);
|
||||
ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,dialog,belle_sip_dialog_state_to_string(dialog_state));
|
||||
|
||||
/*to make sure no cb will destroy op*/
|
||||
sal_op_ref(op);
|
||||
switch(dialog_state) {
|
||||
case BELLE_SIP_DIALOG_NULL:
|
||||
case BELLE_SIP_DIALOG_EARLY: {
|
||||
|
|
@ -312,6 +317,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
}
|
||||
break;
|
||||
}
|
||||
sal_op_unref(op);
|
||||
}
|
||||
|
||||
static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
|
||||
|
|
@ -385,19 +391,31 @@ static void unsupported_method(belle_sip_server_transaction_t* server_transactio
|
|||
*
|
||||
**/
|
||||
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);
|
||||
const char *body;
|
||||
belle_sip_header_content_type_t* content_type;
|
||||
|
||||
if (op&&op->sdp_removal){
|
||||
ms_error("Removed willingly SDP because sal_call_enable_sdp_removal was set to TRUE.");
|
||||
if (op&&op->sdp_handling == SalOpSDPSimulateError){
|
||||
ms_error("Simulating SDP parsing error for op %p", op);
|
||||
*session_desc=NULL;
|
||||
*error=SalReasonNotAcceptable;
|
||||
return -1;
|
||||
} else if( op && op->sdp_handling == SalOpSDPSimulateRemove){
|
||||
ms_error("Simulating no SDP for op %p", op);
|
||||
*session_desc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
body = belle_sip_message_get_body(message);
|
||||
if(body == NULL) {
|
||||
*session_desc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
content_type = belle_sip_message_get_header_by_type(message,belle_sip_header_content_type_t);
|
||||
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) {
|
||||
*session_desc=belle_sdp_session_description_parse(belle_sip_message_get_body(message));
|
||||
*session_desc=belle_sdp_session_description_parse(body);
|
||||
if (*session_desc==NULL) {
|
||||
ms_error("Failed to parse SDP message.");
|
||||
*error=SalReasonNotAcceptable;
|
||||
|
|
@ -684,6 +702,11 @@ int sal_call(SalOp *op, const char *from, const char *to){
|
|||
ms_message("[%s] calling [%s] on op [%p]", from, to, op);
|
||||
invite=sal_op_build_request(op,"INVITE");
|
||||
|
||||
if( invite == NULL ){
|
||||
/* can happen if the op has an invalid address */
|
||||
return -1;
|
||||
}
|
||||
|
||||
sal_op_fill_invite(op,invite);
|
||||
|
||||
sal_op_call_fill_cbs(op);
|
||||
|
|
@ -718,8 +741,14 @@ static void handle_offer_answer_response(SalOp* op, belle_sip_response_t* respon
|
|||
set_sdp_from_desc(BELLE_SIP_MESSAGE(response),op->base.local_media);
|
||||
}else{
|
||||
|
||||
if (op->sdp_answer==NULL)
|
||||
sdp_process(op);
|
||||
if ( op->sdp_answer==NULL )
|
||||
{
|
||||
if( op->sdp_handling == SalOpSDPSimulateRemove ){
|
||||
ms_warning("Simulating SDP removal in answer for op %p", op);
|
||||
} else {
|
||||
sdp_process(op);
|
||||
}
|
||||
}
|
||||
|
||||
if (op->sdp_answer){
|
||||
set_sdp(BELLE_SIP_MESSAGE(response),op->sdp_answer);
|
||||
|
|
|
|||
|
|
@ -198,6 +198,9 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
|
|||
sal_op_subscribe_fill_cbs(op);
|
||||
/*???sal_exosip_fix_route(op); make sure to ha ;lr*/
|
||||
req=sal_op_build_request(op,"SUBSCRIBE");
|
||||
if( req == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
if (eventname){
|
||||
if (op->event) belle_sip_object_unref(op->event);
|
||||
op->event=belle_sip_header_create("Event",eventname);
|
||||
|
|
|
|||
|
|
@ -25,7 +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;
|
||||
op->sdp_handling=sal->default_sdp_handling;
|
||||
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);
|
||||
|
|
@ -149,20 +150,37 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
|
|||
belle_sip_provider_t* prov=op->base.root->prov;
|
||||
belle_sip_request_t *req;
|
||||
belle_sip_uri_t* req_uri;
|
||||
belle_sip_uri_t* to_uri;
|
||||
|
||||
const SalAddress* to_address;
|
||||
const MSList *elem=sal_op_get_route_addresses(op);
|
||||
char token[10];
|
||||
|
||||
/* check that the op has a correct to address */
|
||||
to_address = sal_op_get_to_address(op);
|
||||
if( to_address == NULL ){
|
||||
ms_error("No To: address, cannot build request");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_uri = belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to_address));
|
||||
if( to_uri == NULL ){
|
||||
ms_error("To: address is invalid, cannot build request");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp("REGISTER",method)==0 || op->privacy==SalPrivacyNone) {
|
||||
from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op))
|
||||
,belle_sip_random_token(token,sizeof(token)));
|
||||
,belle_sip_random_token(token,sizeof(token)));
|
||||
} else {
|
||||
from_header=belle_sip_header_from_create2("Anonymous <sip:anonymous@anonymous.invalid>",belle_sip_random_token(token,sizeof(token)));
|
||||
}
|
||||
/*make sure to preserve components like headers or port*/
|
||||
req_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(sal_op_get_to_address(op))));
|
||||
|
||||
req_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)to_uri);
|
||||
belle_sip_uri_set_secure(req_uri,sal_op_is_secure(op));
|
||||
|
||||
to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_to_address(op)),NULL);
|
||||
to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(to_address),NULL);
|
||||
|
||||
req=belle_sip_request_create(
|
||||
req_uri,
|
||||
|
|
@ -217,7 +235,10 @@ int sal_ping(SalOp *op, const char *from, const char *to){
|
|||
void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message) {
|
||||
belle_sip_header_user_agent_t* user_agent=belle_sip_message_get_header_by_type(message,belle_sip_header_user_agent_t);
|
||||
char user_agent_string[256];
|
||||
if(user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
|
||||
if (user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
|
||||
if (op->base.remote_ua!=NULL){
|
||||
ms_free(op->base.remote_ua);
|
||||
}
|
||||
op->base.remote_ua=ms_strdup(user_agent_string);
|
||||
}
|
||||
}
|
||||
|
|
@ -312,7 +333,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
|
|||
}
|
||||
}else{
|
||||
#ifdef TUNNEL_ENABLED
|
||||
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(udplp,belle_sip_tunnel_listening_point_t)){
|
||||
if (udplp && 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");
|
||||
}
|
||||
|
|
@ -778,7 +799,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;
|
||||
void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) {
|
||||
if (handling != SalOpSDPNormal) ms_message("Enabling special SDP handling for SalOp[%p]!", h);
|
||||
h->sdp_handling = handling;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,6 +246,9 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
|
|||
op->dir=SalOpDirOutgoing;
|
||||
|
||||
req=sal_op_build_request(op,"MESSAGE");
|
||||
if (req == NULL ){
|
||||
return -1;
|
||||
}
|
||||
if (sal_op_get_contact_address(op)){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,8 +306,10 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expi
|
|||
belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.from_address),"tag");
|
||||
belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.to_address),"tag");
|
||||
req=sal_op_build_request(op,"SUBSCRIBE");
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
|
||||
if( req ){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
|
||||
}
|
||||
|
||||
return sal_op_send_request(op,req);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,11 @@ int sal_publish_presence(SalOp *op, const char *from, const char *to, int expire
|
|||
|
||||
op->type=SalOpPublish;
|
||||
req=sal_op_build_request(op,"PUBLISH");
|
||||
|
||||
if( req == NULL ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sal_op_get_contact_address(op)){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
|
||||
}
|
||||
|
|
@ -101,6 +106,10 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
|
|||
|
||||
sal_op_publish_fill_cbs(op);
|
||||
req=sal_op_build_request(op,"PUBLISH");
|
||||
if( req == NULL ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sal_op_get_contact_address(op)){
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
|
|||
op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data));
|
||||
}
|
||||
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
|
||||
if (status_code>=200){
|
||||
sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
|
||||
}
|
||||
if(status_code == 200) {
|
||||
/*check service route rfc3608*/
|
||||
belle_sip_header_service_route_t* service_route;
|
||||
|
|
@ -71,6 +74,7 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
|
|||
int sal_register(SalOp *op, const char *proxy, const char *from, int expires){
|
||||
belle_sip_request_t *req;
|
||||
belle_sip_uri_t* req_uri;
|
||||
belle_sip_header_t* accept_header;
|
||||
|
||||
if (op->refresher){
|
||||
belle_sip_refresher_stop(op->refresher);
|
||||
|
|
@ -89,6 +93,8 @@ int sal_register(SalOp *op, const char *proxy, const char *from, int expires){
|
|||
time_t curtime=time(NULL);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)));
|
||||
}
|
||||
accept_header = belle_sip_header_create("Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml");
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), accept_header);
|
||||
belle_sip_message_set_header(BELLE_SIP_MESSAGE(req),(belle_sip_header_t*)sal_op_create_contact(op));
|
||||
return sal_op_send_and_create_refresher(op,req,expires,register_refresher_listener);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,10 +210,18 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
/*only add a c= line within the stream description if address are differents*/
|
||||
if (rtp_addr[0]!='\0' && strcmp(rtp_addr,md->addr)!=0){
|
||||
bool_t inet6;
|
||||
belle_sdp_connection_t *connection;
|
||||
if (strchr(rtp_addr,':')!=NULL){
|
||||
inet6=TRUE;
|
||||
}else inet6=FALSE;
|
||||
belle_sdp_media_description_set_connection(media_desc,belle_sdp_connection_create("IN", inet6 ? "IP6" : "IP4", rtp_addr));
|
||||
connection = belle_sdp_connection_create("IN", inet6 ? "IP6" : "IP4", rtp_addr);
|
||||
if (ms_is_multicast(rtp_addr)) {
|
||||
/*remove session cline in case of multicast*/
|
||||
belle_sdp_session_description_set_connection(session_desc,NULL);
|
||||
if (inet6 == FALSE)
|
||||
belle_sdp_connection_set_ttl(connection,stream->ttl);
|
||||
}
|
||||
belle_sdp_media_description_set_connection(media_desc,connection);
|
||||
}
|
||||
|
||||
if ( stream->bandwidth>0 )
|
||||
|
|
@ -233,6 +241,29 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
}else break;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert DTLS session attribute if needed */
|
||||
if ((stream->proto == SalProtoUdpTlsRtpSavpf) || (stream->proto == SalProtoUdpTlsRtpSavp)) {
|
||||
char* ssrc_attribute = ms_strdup_printf("%u cname:%s",htonl(stream->rtp_ssrc),stream->rtcp_cname);
|
||||
if ((stream->dtls_role != SalDtlsRoleInvalid) && (strlen(stream->dtls_fingerprint)>0)) {
|
||||
switch(stream->dtls_role) {
|
||||
case SalDtlsRoleIsClient:
|
||||
belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("setup","active"));
|
||||
break;
|
||||
case SalDtlsRoleIsServer:
|
||||
belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("setup","passive"));
|
||||
break;
|
||||
case SalDtlsRoleUnset:
|
||||
default:
|
||||
belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("setup","actpass"));
|
||||
break;
|
||||
}
|
||||
belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("fingerprint",stream->dtls_fingerprint));
|
||||
}
|
||||
belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("ssrc",ssrc_attribute)); /* truc de Jehan a virer? */
|
||||
ms_free(ssrc_attribute);
|
||||
}
|
||||
|
||||
switch ( stream->dir ) {
|
||||
case SalStreamSendRecv:
|
||||
/*dir="sendrecv";*/
|
||||
|
|
@ -301,6 +332,13 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
belle_sip_object_unref((belle_sip_object_t*)media_attribute);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* rfc5576
|
||||
* 4.1. The "ssrc" Media Attribute
|
||||
* <ssrc-id> is the synchronization source (SSRC) ID of the
|
||||
* source being described, interpreted as a 32-bit unsigned integer in
|
||||
* network byte order and represented in decimal.*/
|
||||
|
||||
|
||||
belle_sdp_session_description_add_media_description(session_desc, media_desc);
|
||||
}
|
||||
|
|
@ -450,12 +488,15 @@ static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_
|
|||
att_name = belle_sdp_attribute_get_name(attribute);
|
||||
value = belle_sdp_attribute_get_value(attribute);
|
||||
|
||||
if ((keywordcmp("candidate", att_name) == 0) && (value != NULL)) {
|
||||
if ( (nb_ice_candidates < sizeof (stream->ice_candidates)/sizeof(SalIceCandidate))
|
||||
&& (keywordcmp("candidate", att_name) == 0)
|
||||
&& (value != NULL)) {
|
||||
SalIceCandidate *candidate = &stream->ice_candidates[nb_ice_candidates];
|
||||
int nb = sscanf(value, "%s %u UDP %u %s %d typ %s raddr %s rport %d",
|
||||
candidate->foundation, &candidate->componentID, &candidate->priority, candidate->addr, &candidate->port,
|
||||
char proto[4];
|
||||
int nb = sscanf(value, "%s %u %3s %u %s %d typ %s raddr %s rport %d",
|
||||
candidate->foundation, &candidate->componentID, proto, &candidate->priority, candidate->addr, &candidate->port,
|
||||
candidate->type, candidate->raddr, &candidate->rport);
|
||||
if ((nb == 6) || (nb == 8)) nb_ice_candidates++;
|
||||
if (strcasecmp("udp",proto)==0 && ((nb == 7) || (nb == 9))) nb_ice_candidates++;
|
||||
else memset(candidate, 0, sizeof(*candidate));
|
||||
} else if ((keywordcmp("remote-candidates", att_name) == 0) && (value != NULL)) {
|
||||
SalIceRemoteCandidate candidate;
|
||||
|
|
@ -633,8 +674,6 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
stream=&md->streams[md->nb_streams];
|
||||
media=belle_sdp_media_description_get_media ( media_desc );
|
||||
|
||||
memset ( stream,0,sizeof ( *stream ) );
|
||||
|
||||
proto = belle_sdp_media_get_protocol ( media );
|
||||
stream->proto=SalProtoOther;
|
||||
if ( proto ) {
|
||||
|
|
@ -646,12 +685,17 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
stream->proto = SalProtoRtpAvpf;
|
||||
} else if (strcasecmp(proto, "RTP/SAVPF") == 0) {
|
||||
stream->proto = SalProtoRtpSavpf;
|
||||
} else if (strcasecmp(proto, "UDP/TLS/RTP/SAVP") == 0) {
|
||||
stream->proto = SalProtoUdpTlsRtpSavp;
|
||||
} else if (strcasecmp(proto, "UDP/TLS/RTP/SAVPF") == 0) {
|
||||
stream->proto = SalProtoUdpTlsRtpSavpf;
|
||||
} else {
|
||||
strncpy(stream->proto_other,proto,sizeof(stream->proto_other)-1);
|
||||
}
|
||||
}
|
||||
if ( ( cnx=belle_sdp_media_description_get_connection ( media_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) {
|
||||
strncpy ( stream->rtp_addr,belle_sdp_connection_get_address ( cnx ), sizeof ( stream->rtp_addr ) -1 );
|
||||
stream->ttl=belle_sdp_connection_get_ttl(cnx);
|
||||
}
|
||||
|
||||
stream->rtp_port=belle_sdp_media_get_media_port ( media );
|
||||
|
|
@ -701,6 +745,23 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
}
|
||||
}
|
||||
|
||||
/* Read DTLS specific attributes : check is some are found in the stream description otherwise copy the session description one(which are at least set to Invalid) */
|
||||
if (((stream->proto == SalProtoUdpTlsRtpSavpf) || (stream->proto == SalProtoUdpTlsRtpSavp))) {
|
||||
attribute=belle_sdp_media_description_get_attribute(media_desc,"setup");
|
||||
if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){
|
||||
if (strncmp(value, "actpass", 7) == 0) {
|
||||
stream->dtls_role = SalDtlsRoleUnset;
|
||||
} else if (strncmp(value, "active", 6) == 0) {
|
||||
stream->dtls_role = SalDtlsRoleIsClient;
|
||||
} else if (strncmp(value, "passive", 7) == 0) {
|
||||
stream->dtls_role = SalDtlsRoleIsServer;
|
||||
}
|
||||
}
|
||||
if (stream->dtls_role != SalDtlsRoleInvalid && (attribute=belle_sdp_media_description_get_attribute(media_desc,"fingerprint"))) {
|
||||
strncpy(stream->dtls_fingerprint, belle_sdp_attribute_get_value(attribute),sizeof(stream->dtls_fingerprint));
|
||||
}
|
||||
}
|
||||
|
||||
/* Read crypto lines if any */
|
||||
if ((stream->proto == SalProtoRtpSavpf) || (stream->proto == SalProtoRtpSavp)) {
|
||||
sdp_parse_media_crypto_parameters(media_desc, stream);
|
||||
|
|
@ -730,6 +791,8 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S
|
|||
belle_sdp_media_description_t* media_desc;
|
||||
belle_sdp_session_name_t *sname;
|
||||
const char* value;
|
||||
SalDtlsRole session_role=SalDtlsRoleInvalid;
|
||||
int i;
|
||||
|
||||
desc->nb_streams = 0;
|
||||
desc->dir = SalStreamSendRecv;
|
||||
|
|
@ -756,6 +819,25 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S
|
|||
desc->dir=SalStreamInactive;
|
||||
}
|
||||
|
||||
/*DTLS attributes can be defined at session level.*/
|
||||
value=belle_sdp_session_description_get_attribute_value(session_desc,"setup");
|
||||
if (value){
|
||||
if (strncmp(value, "actpass", 7) == 0) {
|
||||
session_role = SalDtlsRoleUnset;
|
||||
} else if (strncmp(value, "active", 6) == 0) {
|
||||
session_role = SalDtlsRoleIsClient;
|
||||
} else if (strncmp(value, "passive", 7) == 0) {
|
||||
session_role = SalDtlsRoleIsServer;
|
||||
}
|
||||
}
|
||||
value=belle_sdp_session_description_get_attribute_value(session_desc,"fingerprint");
|
||||
/*copy dtls attributes to every streams, might be overwritten stream by stream*/
|
||||
for (i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++) {
|
||||
if (value)
|
||||
strncpy(desc->streams[i].dtls_fingerprint, value, sizeof(desc->streams[i].dtls_fingerprint));
|
||||
desc->streams[i].dtls_role=session_role; /*set or reset value*/
|
||||
}
|
||||
|
||||
/* Get ICE remote ufrag and remote pwd, and ice_lite flag */
|
||||
value=belle_sdp_session_description_get_attribute_value(session_desc,"ice-ufrag");
|
||||
if (value) strncpy(desc->ice_ufrag, value, sizeof(desc->ice_ufrag) - 1);
|
||||
|
|
|
|||
106
coreapi/buffer.c
Normal file
106
coreapi/buffer.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
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_buffer_destroy(LinphoneBuffer *buffer) {
|
||||
if (buffer->content) belle_sip_free(buffer->content);
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneBuffer);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneBuffer, belle_sip_object_t,
|
||||
(belle_sip_object_destroy_t)linphone_buffer_destroy,
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
TRUE
|
||||
);
|
||||
|
||||
|
||||
LinphoneBuffer * linphone_buffer_new(void) {
|
||||
LinphoneBuffer *buffer = belle_sip_object_new(LinphoneBuffer);
|
||||
belle_sip_object_ref(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LinphoneBuffer * linphone_buffer_new_from_data(const uint8_t *data, size_t size) {
|
||||
LinphoneBuffer *buffer = linphone_buffer_new();
|
||||
linphone_buffer_set_content(buffer, data, size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LinphoneBuffer * linphone_buffer_new_from_string(const char *data) {
|
||||
LinphoneBuffer *buffer = linphone_buffer_new();
|
||||
linphone_buffer_set_string_content(buffer, data);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
LinphoneBuffer * linphone_buffer_ref(LinphoneBuffer *buffer) {
|
||||
belle_sip_object_ref(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void linphone_buffer_unref(LinphoneBuffer *buffer) {
|
||||
belle_sip_object_unref(buffer);
|
||||
}
|
||||
|
||||
void *linphone_buffer_get_user_data(const LinphoneBuffer *buffer) {
|
||||
return buffer->user_data;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_user_data(LinphoneBuffer *buffer, void *ud) {
|
||||
buffer->user_data = ud;
|
||||
}
|
||||
|
||||
const uint8_t * linphone_buffer_get_content(const LinphoneBuffer *buffer) {
|
||||
return buffer->content;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_content(LinphoneBuffer *buffer, const uint8_t *content, size_t size) {
|
||||
buffer->size = size;
|
||||
if (buffer->content) belle_sip_free(buffer->content);
|
||||
buffer->content = belle_sip_malloc(size + 1);
|
||||
memcpy(buffer->content, content, size);
|
||||
((char *)buffer->content)[size] = '\0';
|
||||
}
|
||||
|
||||
const char * linphone_buffer_get_string_content(const LinphoneBuffer *buffer) {
|
||||
return (const char *)buffer->content;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_string_content(LinphoneBuffer *buffer, const char *content) {
|
||||
buffer->size = strlen(content);
|
||||
if (buffer->content) belle_sip_free(buffer->content);
|
||||
buffer->content = (uint8_t *)belle_sip_strdup(content);
|
||||
}
|
||||
|
||||
size_t linphone_buffer_get_size(const LinphoneBuffer *buffer) {
|
||||
return buffer->size;
|
||||
}
|
||||
|
||||
void linphone_buffer_set_size(LinphoneBuffer *buffer, size_t size) {
|
||||
buffer->size = size;
|
||||
}
|
||||
|
||||
bool_t linphone_buffer_is_empty(const LinphoneBuffer *buffer) {
|
||||
return (buffer->size == 0) ? TRUE : FALSE;
|
||||
}
|
||||
147
coreapi/buffer.h
Normal file
147
coreapi/buffer.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
buffer.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_BUFFER_H_
|
||||
#define LINPHONE_BUFFER_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The LinphoneContent object representing a data buffer.
|
||||
**/
|
||||
typedef struct _LinphoneBuffer LinphoneBuffer;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new empty LinphoneBuffer object.
|
||||
* @return A new LinphoneBuffer object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new(void);
|
||||
|
||||
/**
|
||||
* Create a new LinphoneBuffer object from existing data.
|
||||
* @param[in] data The initial data to store in the LinphoneBuffer.
|
||||
* @param[in] size The size of the initial data to stroe in the LinphoneBuffer.
|
||||
* @return A new LinphoneBuffer object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new_from_data(const uint8_t *data, size_t size);
|
||||
|
||||
/**
|
||||
* Create a new LinphoneBuffer object from a string.
|
||||
* @param[in] data The initial string content of the LinphoneBuffer.
|
||||
* @return A new LinphoneBuffer object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new_from_string(const char *data);
|
||||
|
||||
/**
|
||||
* Acquire a reference to the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The same LinphoneBuffer object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_ref(LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Release reference to the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_buffer_unref(LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Retrieve the user pointer associated with the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The user pointer associated with the buffer.
|
||||
**/
|
||||
LINPHONE_PUBLIC void *linphone_buffer_get_user_data(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Assign a user pointer to the buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @param[in] ud The user pointer to associate with the buffer.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_user_data(LinphoneBuffer *buffer, void *ud);
|
||||
|
||||
/**
|
||||
* Get the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC const uint8_t * linphone_buffer_get_content(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Set the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @param[in] content The content of the data buffer.
|
||||
* @param[in] size The size of the content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_content(LinphoneBuffer *buffer, const uint8_t *content, size_t size);
|
||||
|
||||
/**
|
||||
* Get the string content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object
|
||||
* @return The string content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_buffer_get_string_content(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Set the string content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @param[in] content The string content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_string_content(LinphoneBuffer *buffer, const char *content);
|
||||
|
||||
/**
|
||||
* Get the size of the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object.
|
||||
* @return The size of the content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC size_t linphone_buffer_get_size(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* Set the size of the content of the data buffer.
|
||||
* @param[in] buffer LinphoneBuffer object
|
||||
* @param[in] size The size of the content of the data buffer.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_buffer_set_size(LinphoneBuffer *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Tell whether the LinphoneBuffer is empty.
|
||||
* @param[in] buffer LinphoneBuffer object
|
||||
* @return A boolean value telling whether the LinphoneBuffer is empty or not.
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_buffer_is_empty(const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LINPHONE_CONTENT_H_ */
|
||||
|
|
@ -215,9 +215,9 @@ char * linphone_call_log_to_str(LinphoneCallLog *cl){
|
|||
status=_("missed");
|
||||
break;
|
||||
default:
|
||||
status="unknown";
|
||||
status=_("unknown");
|
||||
}
|
||||
tmp=ortp_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"),
|
||||
tmp=ms_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"),
|
||||
(cl->dir==LinphoneCallIncoming) ? _("Incoming call") : _("Outgoing call"),
|
||||
cl->start_date,
|
||||
from,
|
||||
|
|
|
|||
|
|
@ -27,10 +27,48 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params) {
|
||||
if ((params->media_encryption == LinphoneMediaEncryptionSRTP) && params->avpf_enabled) return SalProtoRtpSavpf;
|
||||
if (params->media_encryption == LinphoneMediaEncryptionSRTP) return SalProtoRtpSavp;
|
||||
if ((params->media_encryption == LinphoneMediaEncryptionDTLS) && params->avpf_enabled) return SalProtoUdpTlsRtpSavpf;
|
||||
if (params->media_encryption == LinphoneMediaEncryptionDTLS) return SalProtoUdpTlsRtpSavp;
|
||||
if (params->avpf_enabled) return SalProtoRtpAvpf;
|
||||
return SalProtoRtpAvp;
|
||||
}
|
||||
|
||||
SalStreamDir sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir) {
|
||||
switch (cpdir) {
|
||||
case LinphoneMediaDirectionInactive:
|
||||
return SalStreamInactive;
|
||||
case LinphoneMediaDirectionSendOnly:
|
||||
return SalStreamSendOnly;
|
||||
case LinphoneMediaDirectionRecvOnly:
|
||||
return SalStreamRecvOnly;
|
||||
case LinphoneMediaDirectionSendRecv:
|
||||
return SalStreamSendRecv;
|
||||
}
|
||||
return SalStreamSendRecv;
|
||||
}
|
||||
|
||||
LinphoneMediaDirection media_direction_from_sal_stream_dir(SalStreamDir dir){
|
||||
switch (dir) {
|
||||
case SalStreamInactive:
|
||||
return LinphoneMediaDirectionInactive;
|
||||
case SalStreamSendOnly:
|
||||
return LinphoneMediaDirectionSendOnly;
|
||||
case SalStreamRecvOnly:
|
||||
return LinphoneMediaDirectionRecvOnly;
|
||||
case SalStreamSendRecv:
|
||||
return LinphoneMediaDirectionSendRecv;
|
||||
}
|
||||
return LinphoneMediaDirectionSendRecv;
|
||||
}
|
||||
|
||||
SalStreamDir get_audio_dir_from_call_params(const LinphoneCallParams *params) {
|
||||
return sal_dir_from_call_params_dir(linphone_call_params_get_audio_direction(params));
|
||||
}
|
||||
|
||||
SalStreamDir get_video_dir_from_call_params(const LinphoneCallParams *params) {
|
||||
return sal_dir_from_call_params_dir(linphone_call_params_get_video_direction(params));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Public functions *
|
||||
|
|
@ -49,6 +87,7 @@ LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){
|
|||
* The management of the custom headers is not optimal. We copy everything while ref counting would be more efficient.
|
||||
*/
|
||||
if (cp->custom_headers) ncp->custom_headers=sal_custom_header_clone(cp->custom_headers);
|
||||
|
||||
return ncp;
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +105,8 @@ void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t en
|
|||
|
||||
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){
|
||||
cp->has_video=enabled;
|
||||
if (enabled && cp->video_dir==LinphoneMediaDirectionInactive)
|
||||
cp->video_dir=LinphoneMediaDirectionSendRecv;
|
||||
}
|
||||
|
||||
const char *linphone_call_params_get_custom_header(const LinphoneCallParams *params, const char *header_name){
|
||||
|
|
@ -156,6 +197,21 @@ bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
|
|||
return cp->has_video;
|
||||
}
|
||||
|
||||
LinphoneMediaDirection linphone_call_params_get_audio_direction(const LinphoneCallParams *cp) {
|
||||
return cp->audio_dir;
|
||||
}
|
||||
|
||||
LinphoneMediaDirection linphone_call_params_get_video_direction(const LinphoneCallParams *cp) {
|
||||
return cp->video_dir;
|
||||
}
|
||||
|
||||
void linphone_call_params_set_audio_direction(LinphoneCallParams *cp,LinphoneMediaDirection dir) {
|
||||
cp->audio_dir=dir;
|
||||
}
|
||||
|
||||
void linphone_call_params_set_video_direction(LinphoneCallParams *cp,LinphoneMediaDirection dir) {
|
||||
cp->video_dir=dir;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
@ -189,7 +245,10 @@ static void _linphone_call_params_destroy(LinphoneCallParams *cp){
|
|||
}
|
||||
|
||||
LinphoneCallParams * linphone_call_params_new(void) {
|
||||
return belle_sip_object_new(LinphoneCallParams);
|
||||
LinphoneCallParams *cp=belle_sip_object_new(LinphoneCallParams);
|
||||
cp->audio_dir=LinphoneMediaDirectionSendRecv;
|
||||
cp->video_dir=LinphoneMediaDirectionSendRecv;
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* DEPRECATED */
|
||||
|
|
|
|||
|
|
@ -30,6 +30,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
/*******************************************************************************
|
||||
* Structures and enums *
|
||||
******************************************************************************/
|
||||
/**
|
||||
* Indicates for a given media the stream direction
|
||||
* */
|
||||
enum _LinphoneMediaDirection {
|
||||
LinphoneMediaDirectionInactive, /** No active media not supported yet*/
|
||||
LinphoneMediaDirectionSendOnly, /** Send only mode*/
|
||||
LinphoneMediaDirectionRecvOnly, /** recv only mode*/
|
||||
LinphoneMediaDirectionSendRecv, /*send receive mode not supported yet*/
|
||||
|
||||
};
|
||||
/**
|
||||
* Typedef for enum
|
||||
**/
|
||||
typedef enum _LinphoneMediaDirection LinphoneMediaDirection;
|
||||
|
||||
/**
|
||||
* Private structure definition for LinphoneCallParams.
|
||||
|
|
@ -247,6 +261,34 @@ LINPHONE_PUBLIC void linphone_call_params_set_session_name(LinphoneCallParams *c
|
|||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
|
||||
|
||||
/**
|
||||
* Get the audio stream direction.
|
||||
* @param[in] cl LinphoneCallParams object
|
||||
* @return The audio stream direction associated with the call params.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneMediaDirection linphone_call_params_get_audio_direction(const LinphoneCallParams *cp);
|
||||
|
||||
/**
|
||||
* Get the video stream direction.
|
||||
* @param[in] cl LinphoneCallParams object
|
||||
* @return The video stream direction associated with the call params.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneMediaDirection linphone_call_params_get_video_direction(const LinphoneCallParams *cp);
|
||||
|
||||
/**
|
||||
* Set the audio stream direction. Only relevant for multicast
|
||||
* @param[in] cl LinphoneCallParams object
|
||||
* @param[in] The audio stream direction associated with this call params.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_params_set_audio_direction(LinphoneCallParams *cp, LinphoneMediaDirection dir);
|
||||
|
||||
/**
|
||||
* Set the video stream direction. Only relevant for multicast
|
||||
* @param[in] cl LinphoneCallParams object
|
||||
* @param[in] The video stream direction associated with this call params.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_params_set_video_direction(LinphoneCallParams *cp, LinphoneMediaDirection dir);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Reference and user data handling functions *
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c
|
|||
static void _clear_early_media_destinations(LinphoneCall *call, MediaStream *ms){
|
||||
RtpSession *session=ms->sessions.rtp_session;
|
||||
rtp_session_clear_aux_remote_addr(session);
|
||||
if (!call->ice_session) rtp_session_set_symmetric_rtp(session,TRUE);/*restore symmetric rtp if ICE is not used*/
|
||||
if (!call->ice_session) rtp_session_set_symmetric_rtp(session,linphone_core_symmetric_rtp_enabled(call->core));/*restore symmetric rtp if ICE is not used*/
|
||||
}
|
||||
|
||||
static void clear_early_media_destinations(LinphoneCall *call){
|
||||
|
|
@ -96,7 +96,23 @@ static void prepare_early_media_forking(LinphoneCall *call){
|
|||
if (call->videostream){
|
||||
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_call_update_frozen_payloads(LinphoneCall *call, SalMediaDescription *result_desc){
|
||||
SalMediaDescription *local=call->localdesc;
|
||||
int i;
|
||||
for(i=0;i<result_desc->nb_streams;++i){
|
||||
MSList *elem;
|
||||
for (elem=result_desc->streams[i].payloads;elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if (is_payload_type_number_available(local->streams[i].already_assigned_payloads, payload_type_get_number(pt), NULL)){
|
||||
/*new codec, needs to be added to the list*/
|
||||
local->streams[i].already_assigned_payloads=ms_list_append(local->streams[i].already_assigned_payloads, payload_type_clone(pt));
|
||||
ms_message("LinphoneCall[%p] : payload type %i %s/%i fmtp=%s added to frozen list.",
|
||||
call, payload_type_get_number(pt), pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
|
||||
|
|
@ -104,7 +120,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
|
|||
bool_t all_muted=FALSE;
|
||||
bool_t send_ringbacktone=FALSE;
|
||||
|
||||
linphone_core_stop_ringing(lc);
|
||||
if (!((call->state == LinphoneCallIncomingEarlyMedia) && (linphone_core_get_ring_during_incoming_early_media(lc)))) {
|
||||
linphone_core_stop_ringing(lc);
|
||||
}
|
||||
if (!new_md) {
|
||||
ms_error("linphone_core_update_streams() called with null media description");
|
||||
return;
|
||||
|
|
@ -181,6 +199,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
|
|||
if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){
|
||||
linphone_core_play_named_tone(lc,LinphoneToneCallOnHold);
|
||||
}
|
||||
linphone_call_update_frozen_payloads(call, new_md);
|
||||
end:
|
||||
if (oldmd)
|
||||
sal_media_description_unref(oldmd);
|
||||
|
|
@ -202,7 +221,7 @@ static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, c
|
|||
|
||||
static bool_t already_a_call_with_remote_address(const LinphoneCore *lc, const LinphoneAddress *remote) {
|
||||
MSList *elem;
|
||||
ms_warning(" searching for already_a_call_with_remote_address.");
|
||||
ms_message("Searching for already_a_call_with_remote_address.");
|
||||
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next){
|
||||
const LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
|
|
@ -215,17 +234,13 @@ static bool_t already_a_call_with_remote_address(const LinphoneCore *lc, const L
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static bool_t already_a_call_pending(LinphoneCore *lc){
|
||||
static bool_t already_an_outgoing_call_pending(LinphoneCore *lc){
|
||||
MSList *elem;
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
if (call->state==LinphoneCallIncomingReceived
|
||||
|| call->state==LinphoneCallIncomingEarlyMedia
|
||||
|| call->state==LinphoneCallOutgoingInit
|
||||
if (call->state==LinphoneCallOutgoingInit
|
||||
|| call->state==LinphoneCallOutgoingProgress
|
||||
|| call->state==LinphoneCallOutgoingEarlyMedia
|
||||
|| call->state==LinphoneCallOutgoingRinging
|
||||
|| call->state==LinphoneCallIdle){ /*case of an incoming call for which ICE candidate gathering is pending.*/
|
||||
|| call->state==LinphoneCallOutgoingRinging){
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -295,17 +310,17 @@ static void call_received(SalOp *h){
|
|||
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.");
|
||||
if ((already_a_call_with_remote_address(lc,from_addr) && prevent_colliding_calls) || already_an_outgoing_call_pending(lc)){
|
||||
ms_warning("Receiving a call while one is initiated, refusing this one with busy message.");
|
||||
sal_call_decline(h,SalReasonBusy,NULL);
|
||||
sal_op_release(h);
|
||||
linphone_address_destroy(from_addr);
|
||||
linphone_address_destroy(to_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
|
@ -321,7 +336,9 @@ static void call_received(SalOp *h){
|
|||
linphone_core_add_call(lc,call);
|
||||
linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */
|
||||
|
||||
if ((_linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) {
|
||||
call->bg_task_id=sal_begin_background_task("liblinphone call notification", NULL, NULL);
|
||||
|
||||
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) {
|
||||
/* Defer ringing until the end of the ICE candidates gathering process. */
|
||||
ms_message("Defer ringing to gather ICE candidates");
|
||||
return;
|
||||
|
|
@ -363,7 +380,11 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md)
|
|||
RtpSession *session=ms->sessions.rtp_session;
|
||||
const char *rtp_addr=new_stream->rtp_addr[0]!='\0' ? new_stream->rtp_addr : md->addr;
|
||||
const char *rtcp_addr=new_stream->rtcp_addr[0]!='\0' ? new_stream->rtcp_addr : md->addr;
|
||||
rtp_session_add_aux_remote_addr_full(session,rtp_addr,new_stream->rtp_port,rtcp_addr,new_stream->rtcp_port);
|
||||
if (ms_is_multicast(rtp_addr))
|
||||
ms_message("Multicast addr [%s/%i] does not need auxiliary rtp's destination for call [%p]",
|
||||
rtp_addr,new_stream->rtp_port,call);
|
||||
else
|
||||
rtp_session_add_aux_remote_addr_full(session,rtp_addr,new_stream->rtp_port,rtcp_addr,new_stream->rtcp_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -408,8 +429,15 @@ static void call_ringing(SalOp *h){
|
|||
if (call->audiostream && audio_stream_started(call->audiostream)){
|
||||
/*streams already started */
|
||||
try_early_media_forking(call,md);
|
||||
return;
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream){
|
||||
/*just request for iframe*/
|
||||
video_stream_send_vfu(call->videostream);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
linphone_core_notify_show_interface(lc);
|
||||
linphone_core_notify_display_status(lc,_("Early media."));
|
||||
linphone_call_set_state(call,LinphoneCallOutgoingEarlyMedia,"Early media");
|
||||
|
|
@ -466,6 +494,14 @@ static void call_accepted(SalOp *op){
|
|||
break;
|
||||
}
|
||||
|
||||
if( (call->prevstate == LinphoneCallOutgoingEarlyMedia) && (md == NULL || sal_media_description_empty(md)) ){
|
||||
/* media description is null or empty because no SDP was received in the 200 OK, we can possibly use the early-media SDP. */
|
||||
if( call->resultdesc != NULL){
|
||||
ms_message("Using early media SDP since none were received with the 200 OK");
|
||||
md = call->resultdesc;
|
||||
}
|
||||
}
|
||||
|
||||
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) ||
|
||||
|
|
@ -597,7 +633,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
|
|||
}
|
||||
}
|
||||
|
||||
if (call->state==LinphoneCallStreamsRunning) {
|
||||
if ( call->state == LinphoneCallStreamsRunning) {
|
||||
/*reINVITE and in-dialogs UPDATE go here*/
|
||||
linphone_core_notify_display_status(lc,_("Call is updated by remote."));
|
||||
call->defer_update=FALSE;
|
||||
|
|
@ -605,8 +641,21 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
|
|||
if (call->defer_update==FALSE){
|
||||
linphone_core_accept_call_update(lc,call,NULL);
|
||||
}
|
||||
if (rmd==NULL)
|
||||
if (rmd==NULL){
|
||||
call->expect_media_in_ack=TRUE;
|
||||
}
|
||||
|
||||
} else if( call->state == LinphoneCallPausedByRemote ){
|
||||
/* Case where no SDP is present and we were paused by remote.
|
||||
* We send back an ACK with our SDP and expect the remote to send its own.
|
||||
* No state change here until an answer is received. */
|
||||
call->defer_update=FALSE;
|
||||
if (call->defer_update==FALSE){
|
||||
_linphone_core_accept_call_update(lc,call,NULL,call->state,linphone_call_state_to_string(call->state));
|
||||
}
|
||||
if (rmd==NULL){
|
||||
call->expect_media_in_ack=TRUE;
|
||||
}
|
||||
} else if (is_update){ /*SIP UPDATE case, can occur in early states*/
|
||||
linphone_call_set_state(call, LinphoneCallEarlyUpdatedByRemote, "EarlyUpdatedByRemote");
|
||||
_linphone_core_accept_call_update(lc,call,NULL,call->prevstate,linphone_call_state_to_string(call->prevstate));
|
||||
|
|
@ -772,8 +821,11 @@ static void call_failure(SalOp *op){
|
|||
char* url = linphone_address_as_string(redirection_to);
|
||||
ms_warning("Redirecting call [%p] to %s",call, url);
|
||||
ms_free(url);
|
||||
linphone_call_create_op(call);
|
||||
linphone_core_start_invite(lc, call, redirection_to);
|
||||
if( call->log->to != NULL ) {
|
||||
linphone_address_unref(call->log->to);
|
||||
}
|
||||
call->log->to = linphone_address_ref(redirection_to);
|
||||
linphone_core_restart_invite(lc, call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1170,14 +1222,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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1208,14 +1264,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){
|
||||
|
|
|
|||
458
coreapi/chat.c
458
coreapi/chat.c
|
|
@ -36,6 +36,140 @@
|
|||
#define COMPOSING_DEFAULT_REFRESH_TIMEOUT 60
|
||||
#define COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT 120
|
||||
|
||||
#define FILE_TRANSFER_KEY_SIZE 32
|
||||
|
||||
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.
|
||||
*/
|
||||
LinphoneChatMessageCbsMsgStateChangedCb 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, LinphoneChatMessageCbsMsgStateChangedCb cb) {
|
||||
cbs->msg_state_changed = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file transfer receive callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The current file transfer receive callback.
|
||||
*/
|
||||
LinphoneChatMessageCbsFileTransferRecvCb 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, LinphoneChatMessageCbsFileTransferRecvCb cb) {
|
||||
cbs->file_transfer_recv = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file transfer send callback.
|
||||
* @param[in] cbs LinphoneChatMessageCbs object.
|
||||
* @return The current file transfer send callback.
|
||||
*/
|
||||
LinphoneChatMessageCbsFileTransferSendCb 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, LinphoneChatMessageCbsFileTransferSendCb 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.
|
||||
*/
|
||||
LinphoneChatMessageCbsFileTransferProgressIndicationCb 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, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb) {
|
||||
cbs->file_transfer_progress_indication = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg);
|
||||
|
||||
|
|
@ -45,7 +179,10 @@ static void process_io_error_upload(void *data, const belle_sip_io_error_event_t
|
|||
if (msg->cb) {
|
||||
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->cb_ud);
|
||||
}
|
||||
#define FILE_TRANSFER_KEY_SIZE 32
|
||||
|
||||
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;
|
||||
|
|
@ -53,6 +190,9 @@ static void process_auth_requested_upload(void *data, belle_sip_auth_event_t *ev
|
|||
if (msg->cb) {
|
||||
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_io_error_download(void *data, const belle_sip_io_error_event_t *event){
|
||||
|
|
@ -61,6 +201,9 @@ static void process_io_error_download(void *data, const belle_sip_io_error_event
|
|||
if (msg->cb) {
|
||||
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;
|
||||
|
|
@ -68,6 +211,9 @@ static void process_auth_requested_download(void *data, belle_sip_auth_event_t *
|
|||
if (msg->cb) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -76,10 +222,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, offset, total);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,27 +247,50 @@ 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)){
|
||||
|
||||
if (chatMsg->file_transfer_information->key != NULL) { /* if we have a key to cipher the message, use it! */
|
||||
if (linphone_content_get_key(chatMsg->file_transfer_information) != NULL) { /* if we have a key to cipher the message, use it! */
|
||||
char *plainBuffer;
|
||||
/* get data from callback to a plainBuffer */
|
||||
/* if this chunk is not the last one, the lenght must be a multiple of block cipher size(16 bytes)*/
|
||||
if (offset+*size<chatMsg->file_transfer_information->size) {
|
||||
if (offset+*size < linphone_content_get_size(chatMsg->file_transfer_information)) {
|
||||
*size -=(*size%16);
|
||||
}
|
||||
plainBuffer = (char *)malloc(*size);
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size);
|
||||
lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), chatMsg->file_transfer_information->key, *size, plainBuffer, (char*)buffer);
|
||||
if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) {
|
||||
LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, *size);
|
||||
if (lb == NULL) *size = 0;
|
||||
else {
|
||||
*size = linphone_buffer_get_size(lb);
|
||||
memcpy(plainBuffer, linphone_buffer_get_content(lb), *size);
|
||||
linphone_buffer_unref(lb);
|
||||
}
|
||||
} else {
|
||||
/* Legacy */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size);
|
||||
}
|
||||
|
||||
lime_encryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), (unsigned char *)linphone_content_get_key(chatMsg->file_transfer_information), *size, plainBuffer, (char*)buffer);
|
||||
free(plainBuffer);
|
||||
/* check if we reach the end of file */
|
||||
if (offset+*size>=chatMsg->file_transfer_information->size) {
|
||||
if (offset+*size >= linphone_content_get_size(chatMsg->file_transfer_information)) {
|
||||
/* conclude file ciphering by calling it context with a zero size */
|
||||
lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), NULL, 0, NULL, NULL);
|
||||
lime_encryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), NULL, 0, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
/* get data from call back directly to the output buffer */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
/* get data from call back */
|
||||
if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) {
|
||||
LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, *size);
|
||||
if (lb == NULL) *size = 0;
|
||||
else {
|
||||
*size = linphone_buffer_get_size(lb);
|
||||
memcpy(buffer, linphone_buffer_get_content(lb), *size);
|
||||
linphone_buffer_unref(lb);
|
||||
}
|
||||
} else {
|
||||
/* Legacy */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +316,6 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
belle_http_request_listener_callbacks_t cbs={0};
|
||||
belle_http_request_listener_t *l;
|
||||
belle_generic_uri_t *uri;
|
||||
belle_http_request_t *req;
|
||||
belle_sip_multipart_body_handler_t *bh;
|
||||
char* ua;
|
||||
char *first_part_header;
|
||||
|
|
@ -153,26 +323,32 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
|
||||
/* shall we encrypt the file */
|
||||
if (msg->chat_room->lc->lime == 1) {
|
||||
char keyBuffer[FILE_TRANSFER_KEY_SIZE]; /* temporary storage of generated key: 192 bits of key + 64 bits of initial vector */
|
||||
/* generate a random 192 bits key + 64 bits of initial vector and store it into the file_transfer_information->key field of the message */
|
||||
msg->file_transfer_information->key = (unsigned char *)malloc(FILE_TRANSFER_KEY_SIZE);
|
||||
sal_get_random_bytes(msg->file_transfer_information->key, FILE_TRANSFER_KEY_SIZE);
|
||||
sal_get_random_bytes((unsigned char *)keyBuffer, FILE_TRANSFER_KEY_SIZE);
|
||||
linphone_content_set_key(msg->file_transfer_information, keyBuffer, FILE_TRANSFER_KEY_SIZE); /* key is duplicated in the content private structure */
|
||||
/* temporary storage for the Content-disposition header value : use a generic filename to not leak it
|
||||
* Actual filename stored in msg->file_transfer_information->name will be set in encrypted message sended to the */
|
||||
first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"filename.txt\"");
|
||||
} else {
|
||||
/* 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 */
|
||||
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 if (linphone_content_get_buffer(msg->file_transfer_information) != NULL) {
|
||||
first_part_bh=(belle_sip_body_handler_t *)belle_sip_memory_body_handler_new_from_buffer(
|
||||
linphone_content_get_buffer(msg->file_transfer_information),
|
||||
linphone_content_get_size(msg->file_transfer_information),
|
||||
NULL,msg);
|
||||
} else {
|
||||
first_part_bh=(belle_sip_body_handler_t *)belle_sip_user_body_handler_new(msg->file_transfer_information->size,NULL,NULL,linphone_chat_message_file_transfer_on_send_body,msg);
|
||||
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(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, first_part_bh);
|
||||
|
|
@ -180,28 +356,28 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
/* 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());
|
||||
uri=belle_generic_uri_parse(linphone_core_get_file_transfer_server(msg->chat_room->lc));
|
||||
req=belle_http_request_create("POST",
|
||||
if (msg->http_request) belle_sip_object_unref(msg->http_request);
|
||||
msg->http_request=belle_http_request_create("POST",
|
||||
uri,
|
||||
belle_sip_header_create("User-Agent",ua),
|
||||
NULL);
|
||||
belle_sip_object_ref(msg->http_request); /* keep a reference to the http request to be able to cancel it during upload */
|
||||
ms_free(ua);
|
||||
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req),BELLE_SIP_BODY_HANDLER(bh));
|
||||
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(msg->http_request),BELLE_SIP_BODY_HANDLER(bh));
|
||||
cbs.process_response=linphone_chat_message_process_response_from_post_file;
|
||||
cbs.process_io_error=process_io_error_upload;
|
||||
cbs.process_auth_requested=process_auth_requested_upload;
|
||||
l=belle_http_request_listener_create_from_callbacks(&cbs,msg);
|
||||
msg->http_request=req; /* update the reference to the http request to be able to cancel it during upload */
|
||||
belle_http_provider_send_request(msg->chat_room->lc->http_provider,req,l);
|
||||
belle_http_provider_send_request(msg->chat_room->lc->http_provider,msg->http_request,l);
|
||||
}
|
||||
|
||||
if (code == 200 ) { /* file has been uplaoded correctly, get server reply and send it */
|
||||
const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
|
||||
belle_sip_object_unref(msg->http_request);
|
||||
msg->http_request = NULL;
|
||||
|
||||
/* TODO Check that the transfer has not been cancelled, note this shall be removed once the belle sip API will provide a cancel request as we shall never reach this part if the transfer is actually cancelled */
|
||||
if (msg->http_request == NULL) {
|
||||
return;
|
||||
}
|
||||
/* if we have an encryption key for the file, we must insert it into the message and restore the correct filename */
|
||||
if (msg->file_transfer_information->key != NULL) {
|
||||
if (linphone_content_get_key(msg->file_transfer_information) != NULL) {
|
||||
/* parse the message body */
|
||||
xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body);
|
||||
|
||||
|
|
@ -218,7 +394,7 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
char *keyb64 = (char *)malloc(b64Size+1);
|
||||
int xmlStringLength;
|
||||
|
||||
b64Size = b64_encode(msg->file_transfer_information->key, FILE_TRANSFER_KEY_SIZE, keyb64, b64Size);
|
||||
b64Size = b64_encode(linphone_content_get_key(msg->file_transfer_information), FILE_TRANSFER_KEY_SIZE, keyb64, b64Size);
|
||||
keyb64[b64Size] = '\0'; /* libxml need a null terminated string */
|
||||
|
||||
/* add the node containing the key to the file-info node */
|
||||
|
|
@ -230,7 +406,7 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
while (fileInfoNodeChildren!=NULL) {
|
||||
if (!xmlStrcmp(fileInfoNodeChildren->name, (const xmlChar *)"file-name")) { /* we found a the file-name node, update its content with the real filename */
|
||||
/* update node content */
|
||||
xmlNodeSetContent(fileInfoNodeChildren, (const xmlChar *)(msg->file_transfer_information->name));
|
||||
xmlNodeSetContent(fileInfoNodeChildren, (const xmlChar *)(linphone_content_get_name(msg->file_transfer_information)));
|
||||
break;
|
||||
}
|
||||
fileInfoNodeChildren = fileInfoNodeChildren->next;
|
||||
|
|
@ -257,6 +433,9 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -401,7 +580,7 @@ LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *
|
|||
* Get a chat room whose peer is the supplied address. If it does not exist yet, it will be created.
|
||||
* @param lc the linphone core
|
||||
* @param addr a linphone address.
|
||||
* @returns #LinphoneChatRoom where messaging can take place.
|
||||
* @return #LinphoneChatRoom where messaging can take place.
|
||||
**/
|
||||
LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr){
|
||||
LinphoneChatRoom *ret = _linphone_core_get_chat_room(lc, addr);
|
||||
|
|
@ -415,7 +594,7 @@ LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAd
|
|||
* Get a chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created.
|
||||
* @param lc The linphone core
|
||||
* @param to The destination address for messages.
|
||||
* @returns #LinphoneChatRoom where messaging can take place.
|
||||
* @return #LinphoneChatRoom where messaging can take place.
|
||||
**/
|
||||
LinphoneChatRoom * linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) {
|
||||
return _linphone_core_get_or_create_chat_room(lc, to);
|
||||
|
|
@ -505,21 +684,25 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
|
|||
belle_http_request_listener_callbacks_t cbs={0};
|
||||
belle_http_request_listener_t *l;
|
||||
belle_generic_uri_t *uri;
|
||||
belle_http_request_t *req;
|
||||
const char *transfer_server = linphone_core_get_file_transfer_server(cr->lc);
|
||||
|
||||
uri=belle_generic_uri_parse(linphone_core_get_file_transfer_server(cr->lc));
|
||||
if (transfer_server == NULL) {
|
||||
ms_warning("Cannot send file transfer message: no file transfer server configured.");
|
||||
return;
|
||||
}
|
||||
uri=belle_generic_uri_parse(transfer_server);
|
||||
|
||||
req=belle_http_request_create("POST",
|
||||
msg->http_request=belle_http_request_create("POST",
|
||||
uri,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
belle_sip_object_ref(msg->http_request); /* keep a reference on the request to be able to cancel it */
|
||||
cbs.process_response=linphone_chat_message_process_response_from_post_file;
|
||||
cbs.process_io_error=process_io_error_upload;
|
||||
cbs.process_auth_requested=process_auth_requested_upload;
|
||||
l=belle_http_request_listener_create_from_callbacks(&cbs,msg); /* give msg to listener to be able to start the actual file upload when server answer a 204 No content */
|
||||
msg->http_request = req; /* keep a reference on the request to be able to cancel it */
|
||||
belle_http_provider_send_request(cr->lc->http_provider,req,l);
|
||||
belle_http_provider_send_request(cr->lc->http_provider,msg->http_request,l);
|
||||
linphone_chat_message_unref(msg);
|
||||
return;
|
||||
}
|
||||
|
|
@ -586,6 +769,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.
|
||||
|
|
@ -609,18 +803,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;
|
||||
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);
|
||||
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;
|
||||
|
|
@ -628,7 +817,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 = ms_new0(LinphoneContent,1);
|
||||
msg->file_transfer_information = linphone_content_new();
|
||||
|
||||
/* parse the message body to get all informations from it */
|
||||
xmlMessageBody = xmlParseDoc((const xmlChar *)sal_msg->text);
|
||||
|
|
@ -644,21 +833,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")) {
|
||||
|
|
@ -669,9 +864,12 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
/* convert the key from base 64 */
|
||||
xmlChar *keyb64 = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1);
|
||||
int keyLength = b64_decode((char *)keyb64, strlen((char *)keyb64), NULL, 0);
|
||||
msg->file_transfer_information->key = (uint8_t *)malloc(keyLength);
|
||||
b64_decode((char *)keyb64, strlen((char *)keyb64), msg->file_transfer_information->key, keyLength);
|
||||
uint8_t *keyBuffer = (uint8_t *)malloc(keyLength);
|
||||
/* decode the key into local key buffer */
|
||||
b64_decode((char *)keyb64, strlen((char *)keyb64), keyBuffer, keyLength);
|
||||
linphone_content_set_key(msg->file_transfer_information, (char *)keyBuffer, keyLength); /* duplicate key value into the linphone content private structure */
|
||||
xmlFree(keyb64);
|
||||
free(keyBuffer);
|
||||
}
|
||||
|
||||
cur=cur->next;
|
||||
|
|
@ -714,7 +912,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);
|
||||
}
|
||||
|
||||
static int linphone_chat_room_remote_refresh_composing_expired(void *data, unsigned int revents) {
|
||||
|
|
@ -768,6 +965,10 @@ static void process_im_is_composing_notification(LinphoneChatRoom *cr, xmlparsin
|
|||
|
||||
cr->remote_is_composing = state;
|
||||
linphone_core_notify_is_composing_received(cr->lc, cr);
|
||||
linphone_free_xml_text_content(state_str);
|
||||
}
|
||||
if (refresh_str != NULL) {
|
||||
linphone_free_xml_text_content(refresh_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -826,6 +1027,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;
|
||||
|
|
@ -852,6 +1054,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;
|
||||
|
|
@ -878,6 +1081,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) {
|
||||
|
|
@ -887,6 +1091,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;
|
||||
|
|
@ -1125,21 +1341,29 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
|
|||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
/* TODO: while belle sip doesn't implement the cancel http request method, test if a request is still linked to the message before forwarding the data to callback */
|
||||
if (chatMsg->http_request == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chatMsg->file_transfer_information->key != NULL) { /* we have a key, we must decrypt the file */
|
||||
if (linphone_content_get_key(chatMsg->file_transfer_information) != NULL) { /* we have a key, we must decrypt the file */
|
||||
/* get data from callback to a plainBuffer */
|
||||
char *plainBuffer = (char *)malloc(size);
|
||||
lime_decryptFile(&(chatMsg->file_transfer_information->cryptoContext), chatMsg->file_transfer_information->key, size, plainBuffer, (char *)buffer);
|
||||
/* call back given by application level */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size);
|
||||
lime_decryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), (unsigned char *)linphone_content_get_key(chatMsg->file_transfer_information), size, plainBuffer, (char *)buffer);
|
||||
if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) {
|
||||
LinphoneBuffer *lb = linphone_buffer_new_from_data((unsigned char *)plainBuffer, size);
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb);
|
||||
linphone_buffer_unref(lb);
|
||||
} else {
|
||||
/* legacy: call back given by application level */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size);
|
||||
}
|
||||
free(plainBuffer);
|
||||
} else { /* regular file, no deciphering */
|
||||
/* 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)) {
|
||||
LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size);
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb);
|
||||
linphone_buffer_unref(lb);
|
||||
} else {
|
||||
/* Legacy: call back given by application level */
|
||||
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -1147,28 +1371,27 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
|
|||
|
||||
|
||||
static LinphoneContent* linphone_chat_create_file_transfer_information_from_headers(const belle_sip_message_t* message ){
|
||||
LinphoneContent *content = ms_new0(LinphoneContent,1);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1186,7 +1409,7 @@ 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);
|
||||
}
|
||||
|
||||
if (message->file_transfer_filepath == NULL) {
|
||||
|
|
@ -1195,10 +1418,12 @@ static void linphone_chat_process_response_headers_from_get_file(void *data, con
|
|||
(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)
|
||||
);
|
||||
belle_sip_body_handler_t *bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(message->file_transfer_filepath, linphone_chat_message_file_transfer_on_progress, message);
|
||||
if (belle_sip_body_handler_get_size(bh) == 0) {
|
||||
/* If the size of the body has not been initialized from the file stat, use the one from the file_transfer_information. */
|
||||
belle_sip_body_handler_set_size(bh, body_size);
|
||||
}
|
||||
belle_sip_message_set_body_handler((belle_sip_message_t *)event->response, bh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1210,40 +1435,46 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle
|
|||
if (code==200) {
|
||||
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
|
||||
LinphoneCore *lc = chatMsg->chat_room->lc;
|
||||
/* if we the file was encrypted, finish the decryption and free context */
|
||||
if (chatMsg->file_transfer_information->key) {
|
||||
lime_decryptFile(&(chatMsg->file_transfer_information->cryptoContext), NULL, 0, NULL, NULL);
|
||||
/* if the file was encrypted, finish the decryption and free context */
|
||||
if (linphone_content_get_key(chatMsg->file_transfer_information) != NULL) {
|
||||
lime_decryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), NULL, 0, NULL, NULL);
|
||||
}
|
||||
/* 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)) {
|
||||
LinphoneBuffer *lb = linphone_buffer_new();
|
||||
linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb);
|
||||
linphone_buffer_unref(lb);
|
||||
} 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 *ud) {
|
||||
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;
|
||||
belle_http_request_t *req;
|
||||
const char *url=message->external_body_url;
|
||||
char* ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version());
|
||||
|
||||
uri=belle_generic_uri_parse(url);
|
||||
|
||||
req=belle_http_request_create("GET",
|
||||
message->http_request=belle_http_request_create("GET",
|
||||
uri,
|
||||
belle_sip_header_create("User-Agent",ua),
|
||||
NULL);
|
||||
|
||||
belle_sip_object_ref(message->http_request); /* keep a reference on the request to be able to cancel the download */
|
||||
ms_free(ua);
|
||||
|
||||
cbs.process_response_headers=linphone_chat_process_response_headers_from_get_file;
|
||||
|
|
@ -1251,12 +1482,22 @@ void linphone_chat_message_start_file_download(LinphoneChatMessage *message, Lin
|
|||
cbs.process_io_error=process_io_error_download;
|
||||
cbs.process_auth_requested=process_auth_requested_download;
|
||||
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 */
|
||||
belle_sip_object_data_set(BELLE_SIP_OBJECT(message->http_request),"message",(void *)message,NULL);
|
||||
message->state = LinphoneChatMessageStateInProgress; /* start the download, status is In Progress */
|
||||
belle_http_provider_send_request(message->chat_room->lc->http_provider,message->http_request,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;
|
||||
message->state = LinphoneChatMessageStateInProgress; /* start the download, status is In Progress */
|
||||
belle_http_provider_send_request(message->chat_room->lc->http_provider,req,l);
|
||||
linphone_chat_message_download_file(message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1264,12 +1505,17 @@ void linphone_chat_message_start_file_download(LinphoneChatMessage *message, Lin
|
|||
* @param msg #LinphoneChatMessage
|
||||
*/
|
||||
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->cb_ud);
|
||||
if (!belle_http_request_is_cancelled(msg->http_request)) {
|
||||
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);
|
||||
belle_http_provider_cancel_request(msg->chat_room->lc->http_provider, msg->http_request);
|
||||
belle_sip_object_unref(msg->http_request);
|
||||
msg->http_request = NULL;
|
||||
if (msg->cb) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1445,12 +1691,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);
|
||||
}
|
||||
|
||||
|
|
@ -1508,20 +1754,30 @@ const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessag
|
|||
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 = ms_new0(LinphoneContent,1);
|
||||
linphone_content_copy(msg->file_transfer_information, initial_content);
|
||||
msg->is_read=TRUE;
|
||||
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)));
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ static void add_local_endpoint(LinphoneConference *conf,LinphoneCore *lc){
|
|||
/**
|
||||
* Returns the sound volume (mic input) of the local participant of the conference.
|
||||
* @param lc the linphone core
|
||||
* @returns the measured input volume expressed in dbm0.
|
||||
* @return the measured input volume expressed in dbm0.
|
||||
**/
|
||||
float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){
|
||||
LinphoneConference *conf=&lc->conf_ctx;
|
||||
|
|
@ -180,7 +180,7 @@ float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){
|
|||
* If the local user was actively part of the call (ie not in paused state), then the local user is automatically entered into the conference.
|
||||
* If the call was in paused state, then it is automatically resumed when entering into the conference.
|
||||
*
|
||||
* @returns 0 if successful, -1 otherwise.
|
||||
* @return 0 if successful, -1 otherwise.
|
||||
**/
|
||||
int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){
|
||||
LinphoneConference *conf=&lc->conf_ctx;
|
||||
|
|
@ -289,7 +289,7 @@ static int convert_conference_to_call(LinphoneCore *lc){
|
|||
* In other words, unless linphone_core_leave_conference() is explicitely called, the last remote participant of a conference is automatically
|
||||
* put in a simple call in running state.
|
||||
*
|
||||
* @returns 0 if successful, -1 otherwise.
|
||||
* @return 0 if successful, -1 otherwise.
|
||||
**/
|
||||
int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){
|
||||
int err;
|
||||
|
|
@ -314,7 +314,7 @@ int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){
|
|||
/**
|
||||
* Indicates whether the local participant is part of the conference.
|
||||
* @param lc the linphone core
|
||||
* @returns TRUE if the local participant is in the conference, FALSE otherwise.
|
||||
* @return TRUE if the local participant is in the conference, FALSE otherwise.
|
||||
**/
|
||||
bool_t linphone_core_is_in_conference(const LinphoneCore *lc){
|
||||
return lc->conf_ctx.local_participant!=NULL;
|
||||
|
|
@ -324,7 +324,7 @@ bool_t linphone_core_is_in_conference(const LinphoneCore *lc){
|
|||
* Moves the local participant out of the conference.
|
||||
* @param lc the linphone core
|
||||
* When the local participant is out of the conference, the remote participants can continue to talk normally.
|
||||
* @returns 0 if successful, -1 otherwise.
|
||||
* @return 0 if successful, -1 otherwise.
|
||||
**/
|
||||
int linphone_core_leave_conference(LinphoneCore *lc){
|
||||
LinphoneConference *conf=&lc->conf_ctx;
|
||||
|
|
@ -342,7 +342,7 @@ int linphone_core_leave_conference(LinphoneCore *lc){
|
|||
* However, by calling linphone_core_leave_conference() and linphone_core_enter_conference() the application can decide to temporarily
|
||||
* move out and in the local participant from the conference.
|
||||
*
|
||||
* @returns 0 if successful, -1 otherwise
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_core_enter_conference(LinphoneCore *lc){
|
||||
LinphoneConference *conf;
|
||||
|
|
@ -363,7 +363,7 @@ int linphone_core_enter_conference(LinphoneCore *lc){
|
|||
*
|
||||
* Merge all established calls (either in LinphoneCallStreamsRunning or LinphoneCallPaused) into a conference.
|
||||
*
|
||||
* @returns 0 if successful, -1 otherwise
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_core_add_all_to_conference(LinphoneCore *lc) {
|
||||
MSList *calls=lc->calls;
|
||||
|
|
@ -384,7 +384,7 @@ int linphone_core_add_all_to_conference(LinphoneCore *lc) {
|
|||
*
|
||||
* All the calls that were merged to the conference are terminated, and the conference resources are destroyed.
|
||||
*
|
||||
* @returns 0 if successful, -1 otherwise
|
||||
* @return 0 if successful, -1 otherwise
|
||||
**/
|
||||
int linphone_core_terminate_conference(LinphoneCore *lc) {
|
||||
MSList *calls=lc->calls;
|
||||
|
|
@ -408,7 +408,7 @@ int linphone_core_terminate_conference(LinphoneCore *lc) {
|
|||
* Typically, after merging two calls into the conference, there is total of 3 participants:
|
||||
* the local participant (or local user), and two remote participants that were the destinations of the two previously establised calls.
|
||||
*
|
||||
* @returns the number of participants to the conference
|
||||
* @return the number of participants to the conference
|
||||
**/
|
||||
int linphone_core_get_conference_size(LinphoneCore *lc) {
|
||||
LinphoneConference *conf=&lc->conf_ctx;
|
||||
|
|
|
|||
243
coreapi/content.c
Normal file
243
coreapi/content.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
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);
|
||||
if (content->lcp.key) belle_sip_free(content->lcp.key);
|
||||
/* note : crypto context is allocated/destroyed by the encryption function */
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent *ref) {
|
||||
obj->owned_fields = TRUE;
|
||||
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));
|
||||
linphone_content_set_key(obj, linphone_content_get_key(ref), linphone_content_get_key_size(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';
|
||||
}
|
||||
|
||||
const 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);
|
||||
}
|
||||
}
|
||||
|
||||
size_t linphone_content_get_key_size(const LinphoneContent *content) {
|
||||
return content->lcp.keyLength;
|
||||
}
|
||||
|
||||
const char * linphone_content_get_key(const LinphoneContent *content) {
|
||||
return content->lcp.key;
|
||||
}
|
||||
|
||||
void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) {
|
||||
if (content->lcp.key != NULL) {
|
||||
belle_sip_free(content->lcp.key);
|
||||
content->lcp.key = NULL;
|
||||
}
|
||||
if (key != NULL) {
|
||||
content->lcp.key = belle_sip_malloc(keyLength);
|
||||
memcpy(content->lcp.key, key, keyLength);
|
||||
}
|
||||
}
|
||||
|
||||
/* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */
|
||||
void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) {
|
||||
return &(content->lcp.cryptoContext);
|
||||
}
|
||||
|
||||
|
||||
LinphoneContent * linphone_content_new(void) {
|
||||
LinphoneContent *content = belle_sip_object_new(LinphoneContent);
|
||||
belle_sip_object_ref(content);
|
||||
content->owned_fields = TRUE;
|
||||
content->lcp.cryptoContext = NULL; /* this field is managed externally by encryption/decryption functions so be careful to initialise it to NULL */
|
||||
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;
|
||||
}
|
||||
231
coreapi/content.h
Normal file
231
coreapi/content.h
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
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 */
|
||||
char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */
|
||||
size_t keyLength; /**< Length of key in bytes */
|
||||
void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 const 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_ */
|
||||
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
|
||||
/**
|
||||
* @addtogroup linphone_dict
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
**/
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s
|
|||
linphone_core_notify_publish_state_changed(lev->lc,lev,state);
|
||||
switch(state){
|
||||
case LinphonePublishCleared:
|
||||
linphone_event_unref(lev);
|
||||
if (lev->expires!=-1)
|
||||
linphone_event_unref(lev);
|
||||
break;
|
||||
case LinphonePublishOk:
|
||||
case LinphonePublishError:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define LINPHONEEVENT_H
|
||||
|
||||
/**
|
||||
* @addtogroup subscriptions
|
||||
* @addtogroup event_api
|
||||
* @{
|
||||
**/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
#
|
||||
############################################################################
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@
|
|||
|
||||
/**
|
||||
* @defgroup media_parameters Controlling media parameters
|
||||
*<b> Multicast </b>
|
||||
*<br> Call using rtp multicast addresses are supported for both audio and video with some limitations. Limitations are, no stun, no ice, no encryption.
|
||||
*<br><li> Incoming call with multicast address are automatically accepted. The called party switches in a media receive only mode.
|
||||
*<br><li> Outgoing call willing to send media to a multicast address can activate multicast using \link linphone_core_enable_video_multicast\endlink or
|
||||
*\link linphone_core_enable_audio_multicast\endlink . The calling party switches in a media listen send only mode.
|
||||
**/
|
||||
|
||||
/**
|
||||
|
|
@ -216,6 +221,12 @@ void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddre
|
|||
*
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup event_api Managing generic subscriptions and publishes
|
||||
* The LinphoneEvent api allows application to control subscriptions, receive notifications and make publish to peers, in a generic manner.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup misc Miscenalleous: logs, version strings, config storage
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -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 offset, size_t total) {
|
||||
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)((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,55 +63,37 @@ 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 LinphoneBuffer *buffer){
|
||||
FILE* file=NULL;
|
||||
if (!linphone_chat_message_get_user_data(message)) {
|
||||
/*first chunk, creating file*/
|
||||
file = fopen("receive_file.dump","wb");
|
||||
linphone_chat_message_set_user_data(message,(void*)file); /*store fd for next chunks*/
|
||||
} else {
|
||||
/*next chunk*/
|
||||
file = (FILE*)linphone_chat_message_get_user_data(message);
|
||||
}
|
||||
|
||||
if (size) {
|
||||
printf("File transfert completed\n");
|
||||
linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message));
|
||||
linphone_chat_message_destroy(message);
|
||||
fclose(file);
|
||||
running=FALSE;
|
||||
} else { /* store content on a file*/
|
||||
if (fwrite(buff,size,1,file)==-1){
|
||||
ms_warning("file_transfer_received() write failed: %s",strerror(errno));
|
||||
}
|
||||
file = (FILE*)linphone_chat_message_get_user_data(message);
|
||||
if (linphone_buffer_is_empty(buffer)) {
|
||||
printf("File transfert completed\n");
|
||||
linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message));
|
||||
linphone_chat_message_destroy(message);
|
||||
fclose(file);
|
||||
running=FALSE;
|
||||
} else { /* store content on a file*/
|
||||
if (fwrite(linphone_buffer_get_content(buffer),linphone_buffer_get_size(buffer),1,file)==-1){
|
||||
ms_warning("file_transfer_received() write failed: %s",strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
int offset=-1;
|
||||
|
||||
if (!linphone_chat_message_get_user_data(message)) {
|
||||
/*first chunk*/
|
||||
offset=0;
|
||||
} else {
|
||||
/*subsequent chunk*/
|
||||
offset = (int)((long)(linphone_chat_message_get_user_data(message))&0x00000000FFFFFFFF);
|
||||
}
|
||||
*size = MIN(*size,sizeof(big_file)-offset); /*updating content->size with minimun between remaining data and requested size*/
|
||||
|
||||
if (*size==0) {
|
||||
/*end of file*/
|
||||
return;
|
||||
}
|
||||
memcpy(buff,big_file+offset,*size);
|
||||
|
||||
/*store offset for next chunk*/
|
||||
linphone_chat_message_set_user_data(message,(void*)(offset+*size));
|
||||
|
||||
static LinphoneBuffer * file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size){
|
||||
size_t size_to_send = MIN(size, sizeof(big_file) - offset);
|
||||
if (size == 0) return linphone_buffer_new(); /*end of file*/
|
||||
return linphone_buffer_new_from_data((uint8_t *)big_file + offset, size_to_send);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -130,7 +112,7 @@ 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, NULL);
|
||||
|
||||
|
|
@ -144,8 +126,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))
|
||||
|
|
@ -159,15 +142,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;
|
||||
|
||||
|
||||
|
|
@ -188,20 +162,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){
|
||||
|
|
@ -211,6 +195,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");
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ 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.LogCollectionUploadState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
|
|
@ -322,4 +323,17 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadProgressIndication(LinphoneCore lc, int offset, int total) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadStateChanged(LinphoneCore lc,
|
||||
LogCollectionUploadState state, String info) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ 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.LogCollectionUploadState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
|
|
@ -241,5 +242,18 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadProgressIndication(LinphoneCore lc, int offset, int total) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadStateChanged(LinphoneCore lc,
|
||||
LogCollectionUploadState state, String info) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,16 @@ 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.LogCollectionUploadState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
|
|
@ -36,9 +40,6 @@ import org.linphone.core.LinphoneEvent;
|
|||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.core.LinphoneCore.GlobalState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.core.PublishState;
|
||||
import org.linphone.core.SubscriptionState;
|
||||
|
||||
|
|
@ -243,5 +244,18 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadProgressIndication(LinphoneCore lc, int offset, int total) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadStateChanged(LinphoneCore lc,
|
||||
LogCollectionUploadState state, String info) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ 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.LogCollectionUploadState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
|
|
@ -274,6 +275,16 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadProgressIndication(LinphoneCore lc, int offset, int total) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void uploadStateChanged(LinphoneCore lc,
|
||||
LogCollectionUploadState state, String info) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
103
coreapi/info.c
103
coreapi/info.c
|
|
@ -29,111 +29,24 @@
|
|||
|
||||
|
||||
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->key) {
|
||||
ms_free(obj->key);
|
||||
obj->key=NULL;
|
||||
}
|
||||
if (ref->key) {
|
||||
obj->key = (unsigned char *)ms_strdup((const char *)ref->key);
|
||||
}
|
||||
|
||||
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);
|
||||
if (obj->key) ms_free(obj->key);
|
||||
}
|
||||
|
||||
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;
|
||||
obj->name = NULL;
|
||||
obj->key = NULL;
|
||||
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;
|
||||
obj->name = NULL;
|
||||
obj->key = NULL;
|
||||
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;
|
||||
}
|
||||
|
|
@ -159,7 +72,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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -189,14 +102,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){
|
||||
|
|
@ -204,7 +117,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
#include "private.h"
|
||||
#include "lpconfig.h"
|
||||
|
||||
static const char *_tunnel_mode_str[3] = { "disable", "enable", "auto" };
|
||||
|
||||
LinphoneTunnel* linphone_core_get_tunnel(const LinphoneCore *lc){
|
||||
return lc->tunnel;
|
||||
}
|
||||
|
|
@ -234,7 +232,7 @@ void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){
|
|||
}
|
||||
|
||||
void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTunnelMode mode){
|
||||
lp_config_set_string(config(tunnel),"tunnel","mode", tunnel_mode_to_string(mode));
|
||||
lp_config_set_string(config(tunnel),"tunnel","mode", linphone_tunnel_mode_to_string(mode));
|
||||
bcTunnel(tunnel)->setMode(mode);
|
||||
}
|
||||
|
||||
|
|
@ -336,31 +334,13 @@ static void my_ortp_logv(OrtpLogLevel level, const char *fmt, va_list args){
|
|||
ortp_logv(level,fmt,args);
|
||||
}
|
||||
|
||||
LinphoneTunnelMode string_to_tunnel_mode(const char *string) {
|
||||
if(string != NULL) {
|
||||
int i;
|
||||
for(i=0; i<3 && strcmp(string, _tunnel_mode_str[i]) != 0; i++);
|
||||
if(i<3) {
|
||||
return (LinphoneTunnelMode)i;
|
||||
} else {
|
||||
ms_error("Invalid tunnel mode '%s'", string);
|
||||
return LinphoneTunnelModeDisable;
|
||||
}
|
||||
} else {
|
||||
return LinphoneTunnelModeDisable;
|
||||
}
|
||||
}
|
||||
|
||||
const char *tunnel_mode_to_string(LinphoneTunnelMode mode) {
|
||||
return _tunnel_mode_str[mode];
|
||||
}
|
||||
|
||||
/**
|
||||
* Startup tunnel using configuration.
|
||||
* Called internally from linphonecore at startup.
|
||||
*/
|
||||
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
|
||||
LinphoneTunnelMode mode = string_to_tunnel_mode(lp_config_get_string(config(tunnel), "tunnel", "mode", NULL));
|
||||
LinphoneTunnelMode mode = linphone_tunnel_mode_from_string(lp_config_get_string(config(tunnel), "tunnel", "mode", NULL));
|
||||
bool_t tunnelizeSIPPackets = (bool_t)lp_config_get_int(config(tunnel), "tunnel", "sip", TRUE);
|
||||
linphone_tunnel_enable_logs_with_handler(tunnel,TRUE,my_ortp_logv);
|
||||
linphone_tunnel_load_config(tunnel);
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@ typedef enum _LinphoneTunnelMode {
|
|||
* @return An LinphoneTunnelMode enum. If the passed string is NULL or
|
||||
* does not match with any mode, the LinphoneTunnelModeDisable is returned.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneTunnelMode string_to_tunnel_mode(const char *string);
|
||||
LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_mode_from_string(const char *string);
|
||||
|
||||
/**
|
||||
* Convert a tunnel mode enum into string
|
||||
* @param mode Enum to convert
|
||||
* @return "disable", "enable" or "auto"
|
||||
*/
|
||||
LINPHONE_PUBLIC const char *tunnel_mode_to_string(LinphoneTunnelMode mode);
|
||||
LINPHONE_PUBLIC const char *linphone_tunnel_mode_to_string(LinphoneTunnelMode mode);
|
||||
|
||||
/**
|
||||
* Create a new tunnel configuration
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -126,28 +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 */
|
||||
unsigned char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */
|
||||
void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -279,7 +257,7 @@ LINPHONE_PUBLIC int linphone_payload_type_get_normal_bitrate(const LinphonePaylo
|
|||
* @param[in] pt LinphonePayloadType object
|
||||
* @return The mime type.
|
||||
*/
|
||||
LINPHONE_PUBLIC char * linphone_payload_type_get_mime_type(const LinphonePayloadType *pt);
|
||||
LINPHONE_PUBLIC const char * linphone_payload_type_get_mime_type(const LinphonePayloadType *pt);
|
||||
|
||||
/**
|
||||
* Get the number of channels.
|
||||
|
|
@ -309,7 +287,8 @@ typedef enum _LinphoneAVPFMode LinphoneAVPFMode;
|
|||
enum _LinphoneMediaEncryption {
|
||||
LinphoneMediaEncryptionNone, /**< No media encryption is used */
|
||||
LinphoneMediaEncryptionSRTP, /**< Use SRTP media encryption */
|
||||
LinphoneMediaEncryptionZRTP /**< Use ZRTP media encryption */
|
||||
LinphoneMediaEncryptionZRTP, /**< Use ZRTP media encryption */
|
||||
LinphoneMediaEncryptionDTLS /**< Use DTLS media encryption */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -388,15 +367,19 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
|
|||
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonefriend.h"
|
||||
#include "event.h"
|
||||
#include "buffer.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/buffer.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);
|
||||
|
|
@ -414,12 +397,19 @@ LINPHONE_PUBLIC void linphone_address_set_domain(LinphoneAddress *uri, const cha
|
|||
LINPHONE_PUBLIC void linphone_address_set_port(LinphoneAddress *uri, int port);
|
||||
/*remove tags, params etc... so that it is displayable to the user*/
|
||||
LINPHONE_PUBLIC void linphone_address_clean(LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *addr);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_get_secure(const LinphoneAddress *addr);
|
||||
LINPHONE_PUBLIC void linphone_address_set_secure(LinphoneAddress *addr, bool_t enabled);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_is_sip(const LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri);
|
||||
LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,LinphoneTransportType type);
|
||||
LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u);
|
||||
LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2);
|
||||
LINPHONE_PUBLIC bool_t linphone_address_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);
|
||||
|
||||
/**
|
||||
|
|
@ -497,6 +487,8 @@ enum _LinphoneIceState{
|
|||
**/
|
||||
typedef enum _LinphoneIceState LinphoneIceState;
|
||||
|
||||
LINPHONE_PUBLIC const char *linphone_ice_state_to_string(LinphoneIceState state);
|
||||
|
||||
/**
|
||||
* Enum describing uPnP states.
|
||||
* @ingroup initializing
|
||||
|
|
@ -554,6 +546,8 @@ struct _LinphoneCallStats {
|
|||
float local_late_rate; /**<percentage of packet received too late over last second*/
|
||||
float local_loss_rate; /**<percentage of lost packet over last second*/
|
||||
int updated; /**< Tell which RTCP packet has been updated (received_rtcp or sent_rtcp). Can be either LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE or LINPHONE_CALL_STATS_SENT_RTCP_UPDATE */
|
||||
float rtcp_download_bandwidth; /**<RTCP download bandwidth measurement of received stream, expressed in kbit/s, including IP/UDP/RTP headers*/
|
||||
float rtcp_upload_bandwidth; /**<RTCP download bandwidth measurement of sent stream, expressed in kbit/s, including IP/UDP/RTP headers*/
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -682,7 +676,14 @@ LINPHONE_PUBLIC void *linphone_call_get_user_data(const LinphoneCall *call);
|
|||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *ud);
|
||||
|
||||
/**
|
||||
* Get the core that has created the specified call.
|
||||
* @param[in] call LinphoneCall object
|
||||
* @return The LinphoneCore object that has created the specified call.
|
||||
* @ingroup call_control
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCore *linphone_call_get_core(const LinphoneCall *call);
|
||||
|
||||
LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state(const LinphoneCall *call);
|
||||
LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
|
||||
|
||||
|
|
@ -739,7 +740,7 @@ LINPHONE_PUBLIC bool_t linphone_call_media_in_progress(LinphoneCall *call);
|
|||
* 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.
|
||||
* @return 0 if successful, -1 on error.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_call_send_dtmf(LinphoneCall *lc,char dtmf);
|
||||
|
||||
|
|
@ -750,7 +751,7 @@ LINPHONE_PUBLIC int linphone_call_send_dtmf(LinphoneCall *lc,char dtmf);
|
|||
* 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.
|
||||
* @return -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);
|
||||
|
||||
|
|
@ -765,6 +766,19 @@ LINPHONE_PUBLIC int linphone_call_send_dtmfs(LinphoneCall *call,char *dtmfs);
|
|||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_cancel_dtmfs(LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Get the native window handle of the video window, casted as an unsigned long.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC unsigned long linphone_call_get_native_video_window_id(const LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Set the native video window id where the video is to be displayed.
|
||||
* For MacOS, Linux, Windows: if not set or 0 a window will be automatically created, unless the special id -1 is given.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_set_native_video_window_id(LinphoneCall *call, unsigned long id);
|
||||
|
||||
/**
|
||||
* Return TRUE if this call is currently part of a conference
|
||||
* @param call #LinphoneCall
|
||||
|
|
@ -972,7 +986,7 @@ LINPHONE_PUBLIC int linphone_proxy_config_get_quality_reporting_interval(Linphon
|
|||
/**
|
||||
* Get the registration state of the given proxy config.
|
||||
* @param[in] obj #LinphoneProxyConfig object.
|
||||
* @returns The registration state of the proxy config.
|
||||
* @return The registration state of the proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyConfig *obj);
|
||||
|
||||
|
|
@ -981,21 +995,21 @@ LINPHONE_PUBLIC bool_t linphone_proxy_config_is_registered(const LinphoneProxyCo
|
|||
/**
|
||||
* Get the domain name of the given proxy config.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @returns The domain name of the proxy config.
|
||||
* @return The domain name of the proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* Get the realm of the given proxy config.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @returns The realm of the proxy config.
|
||||
* @return The realm of the proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg);
|
||||
/**
|
||||
* Set the realm of the given proxy config.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @param[in] realm New realm value.
|
||||
* @returns The realm of the proxy config.
|
||||
* @return The realm of the proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char * realm);
|
||||
|
||||
|
|
@ -1016,7 +1030,7 @@ LINPHONE_PUBLIC const char* linphone_proxy_config_get_contact_uri_parameters(con
|
|||
/**
|
||||
* Get the #LinphoneCore object to which is associated the #LinphoneProxyConfig.
|
||||
* @param[in] obj #LinphoneProxyConfig object.
|
||||
* @returns The #LinphoneCore object to which is associated the #LinphoneProxyConfig.
|
||||
* @return The #LinphoneCore object to which is associated the #LinphoneProxyConfig.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig *obj);
|
||||
|
||||
|
|
@ -1026,22 +1040,22 @@ LINPHONE_PUBLIC const char * linphone_proxy_config_get_dial_prefix(const Linphon
|
|||
/**
|
||||
* Get the reason why registration failed when the proxy config state is LinphoneRegistrationFailed.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @returns The reason why registration failed for this proxy config.
|
||||
* @return The reason why registration failed for this proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* Get detailed information why registration failed when the proxy config state is LinphoneRegistrationFailed.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @returns The details why registration failed for this proxy config.
|
||||
* @return The details why registration failed for this proxy config.
|
||||
**/
|
||||
LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/*
|
||||
* return the transport from either : service route, route, or addr
|
||||
* @returns cfg object
|
||||
* @return transport as string (I.E udp, tcp, tls, dtls)*/
|
||||
|
||||
/**
|
||||
* Get the transport from either service route, route or addr.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @return The transport as a string (I.E udp, tcp, tls, dtls)
|
||||
**/
|
||||
LINPHONE_PUBLIC const char* linphone_proxy_config_get_transport(const LinphoneProxyConfig *cfg);
|
||||
|
||||
|
||||
|
|
@ -1050,10 +1064,27 @@ LINPHONE_PUBLIC void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg);
|
|||
LINPHONE_PUBLIC void linphone_proxy_config_set_sip_setup(LinphoneProxyConfig *cfg, const char *type);
|
||||
SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig *cfg);
|
||||
LINPHONE_PUBLIC SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222
|
||||
* Detect if the given input is a phone number or not.
|
||||
* @param proxy #LinphoneProxyConfig argument, unused yet but may contain useful data. Can be NULL.
|
||||
* @param username string to parse.
|
||||
* @return TRUE if input is a phone number, FALSE otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig *proxy, const char *username);
|
||||
|
||||
/**
|
||||
* Normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222
|
||||
* or +33888444222 depending on the #LinphoneProxyConfig argument. This function will always
|
||||
* generate a normalized username; if input is not a phone number, output will be a copy of input.
|
||||
* @param proxy #LinphoneProxyConfig object containing country code and/or escape symbol.
|
||||
* @param username the string to parse
|
||||
* @param result the newly normalized number
|
||||
* @param result_len the size of the normalized number \a result
|
||||
* @return TRUE if a phone number was recognized, FALSE otherwise.
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len);
|
||||
LINPHONE_PUBLIC bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username,
|
||||
char *result, size_t result_len);
|
||||
|
||||
/**
|
||||
* Set default privacy policy for all calls routed through this proxy.
|
||||
|
|
@ -1124,6 +1155,21 @@ LINPHONE_PUBLIC LinphoneAVPFMode linphone_proxy_config_get_avpf_mode(const Linph
|
|||
**/
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_mode(LinphoneProxyConfig *cfg, LinphoneAVPFMode mode);
|
||||
|
||||
/**
|
||||
* Obtain the value of a header sent by the server in last answer to REGISTER.
|
||||
* @param cfg the proxy config object
|
||||
* @param header_name the header name for which to fetch corresponding value
|
||||
* @return the value of the queried header.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, const char *header_name);
|
||||
|
||||
/**
|
||||
* Set the value of a custom header sent to the server in REGISTERs request.
|
||||
* @param cfg the proxy config object
|
||||
* @param header_name the header name
|
||||
* @param header_value the header's value
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_set_custom_header(LinphoneProxyConfig *cfg, const char *header_name, const char *header_value);
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
@ -1316,7 +1362,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;
|
||||
|
|
@ -1341,12 +1392,47 @@ typedef enum _LinphoneChatMessageState {
|
|||
|
||||
/**
|
||||
* Call back used to notify message delivery status
|
||||
*@param msg #LinphoneChatMessage object
|
||||
*@param status LinphoneChatMessageState
|
||||
*@param ud application user data
|
||||
* @param msg #LinphoneChatMessage object
|
||||
* @param status LinphoneChatMessageState
|
||||
* @param ud application user data
|
||||
* @deprecated
|
||||
*/
|
||||
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 (*LinphoneChatMessageCbsMsgStateChangedCb)(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 buffer #LinphoneBuffer holding the received data. Empty buffer means end of file.
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer);
|
||||
|
||||
/**
|
||||
* File transfer send callback prototype. This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0.
|
||||
* @param message #LinphoneChatMessage message from which the body is received.
|
||||
* @param content #LinphoneContent outgoing content
|
||||
* @param offset the offset in the file from where to get the data to be sent
|
||||
* @param size the number of bytes expected by the framework
|
||||
* @return A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file.
|
||||
*/
|
||||
typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, 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 (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(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);
|
||||
|
|
@ -1397,10 +1483,26 @@ 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);
|
||||
|
||||
/**
|
||||
* Mark all messages of the conversation as read
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr);
|
||||
/**
|
||||
* Delete a message from the chat room history.
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
|
||||
* @param[in] msg The #LinphoneChatMessage object to remove.
|
||||
*/
|
||||
|
||||
LINPHONE_PUBLIC void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
/**
|
||||
* Delete all messages from the history
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr);
|
||||
/**
|
||||
* Gets the number of messages in a chat room.
|
||||
|
|
@ -1431,6 +1533,11 @@ LINPHONE_PUBLIC void linphone_chat_room_compose(LinphoneChatRoom *cr);
|
|||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Gets the number of unread messages in the chatroom.
|
||||
* @param[in] cr The "LinphoneChatRoom object corresponding to the conversation.
|
||||
* @return the number of unread messages.
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr);
|
||||
|
|
@ -1458,6 +1565,7 @@ LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const Li
|
|||
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, 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);
|
||||
|
|
@ -1477,6 +1585,21 @@ LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMess
|
|||
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 LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs);
|
||||
LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb);
|
||||
LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferProgressIndicationCb 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, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
@ -1516,7 +1639,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
|
||||
|
|
@ -1761,20 +1884,43 @@ 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 arguments set to NULL
|
||||
* @returns newly allocated vtable
|
||||
* @return newly allocated vtable
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCoreVTable *linphone_core_v_table_new();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return 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
|
||||
* @return 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
|
||||
|
|
@ -1823,7 +1969,7 @@ typedef enum _LinphoneLogCollectionState {
|
|||
/**
|
||||
* Tells whether the linphone core log collection is enabled.
|
||||
* @ingroup misc
|
||||
* @returns The state of the linphone core log collection.
|
||||
* @return The state of the linphone core log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneLogCollectionState linphone_core_log_collection_enabled(void);
|
||||
|
||||
|
|
@ -1837,7 +1983,7 @@ LINPHONE_PUBLIC void linphone_core_enable_log_collection(LinphoneLogCollectionSt
|
|||
/**
|
||||
* 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.
|
||||
* @return The path where the log files will be written.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_log_collection_path(void);
|
||||
|
||||
|
|
@ -1851,7 +1997,7 @@ 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.
|
||||
* @return The prefix of the filenames used for log collection.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_log_collection_prefix(void);
|
||||
|
||||
|
|
@ -1865,7 +2011,7 @@ 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.
|
||||
* @return 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);
|
||||
|
||||
|
|
@ -2049,7 +2195,7 @@ LINPHONE_PUBLIC int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall
|
|||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] call The #LinphoneCall to redirect.
|
||||
* @param[in] redirect_uri The URI to redirect the call to.
|
||||
* @returns 0 if successful, -1 on error.
|
||||
* @return 0 if successful, -1 on error.
|
||||
* @ingroup call_control
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_core_redirect_call(LinphoneCore *lc, LinphoneCall *call, const char *redirect_uri);
|
||||
|
|
@ -2157,7 +2303,7 @@ LINPHONE_PUBLIC void linphone_core_enable_dns_srv(LinphoneCore *lc, bool_t enabl
|
|||
/**
|
||||
* Tells whether DNS SRV resolution is enabled.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns TRUE if DNS SRV resolution is enabled, FALSE if disabled.
|
||||
* @return TRUE if DNS SRV resolution is enabled, FALSE if disabled.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_dns_srv_enabled(const LinphoneCore *lc);
|
||||
|
|
@ -2171,11 +2317,15 @@ LINPHONE_PUBLIC const MSList *linphone_core_get_video_codecs(const LinphoneCore
|
|||
|
||||
LINPHONE_PUBLIC int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_enable_generic_confort_noise(LinphoneCore *lc, bool_t enabled);
|
||||
|
||||
LINPHONE_PUBLIC bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Tells whether the specified payload type is enabled.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] pt The #LinphonePayloadType we want to know is enabled or not.
|
||||
* @returns TRUE if the payload type is enabled, FALSE if disabled.
|
||||
* @return TRUE if the payload type is enabled, FALSE if disabled.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt);
|
||||
|
|
@ -2184,7 +2334,7 @@ LINPHONE_PUBLIC bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, cons
|
|||
* Tells whether the specified payload type represents a variable bitrate codec.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] pt The #LinphonePayloadType we want to know
|
||||
* @returns TRUE if the payload type represents a VBR codec, FALSE if disabled.
|
||||
* @return TRUE if the payload type represents a VBR codec, FALSE if disabled.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayloadType *pt);
|
||||
|
|
@ -2239,8 +2389,19 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, Linphone
|
|||
*/
|
||||
LINPHONE_PUBLIC LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ;
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* Returns the payload type number assigned for this codec.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt);
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. THis function is to be used mainly for tests, in order
|
||||
* to override the automatic assignment mechanism.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number);
|
||||
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt);
|
||||
|
||||
LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt);
|
||||
|
|
@ -2309,7 +2470,7 @@ LINPHONE_PUBLIC void linphone_core_enable_audio_adaptive_jittcomp(LinphoneCore *
|
|||
/**
|
||||
* Tells whether the audio adaptive jitter compensation is enabled.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @returns TRUE if the audio adaptive jitter compensation is enabled, FALSE otherwise.
|
||||
* @return TRUE if the audio adaptive jitter compensation is enabled, FALSE otherwise.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_audio_adaptive_jittcomp_enabled(LinphoneCore *lc);
|
||||
|
|
@ -2329,7 +2490,7 @@ LINPHONE_PUBLIC void linphone_core_enable_video_adaptive_jittcomp(LinphoneCore *
|
|||
/**
|
||||
* Tells whether the video adaptive jitter compensation is enabled.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @returns TRUE if the video adaptive jitter compensation is enabled, FALSE otherwise.
|
||||
* @return TRUE if the video adaptive jitter compensation is enabled, FALSE otherwise.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_video_adaptive_jittcomp_enabled(LinphoneCore *lc);
|
||||
|
|
@ -2408,7 +2569,7 @@ LINPHONE_PUBLIC void linphone_core_set_stun_server(LinphoneCore *lc, const char
|
|||
/**
|
||||
* Get the STUN server address being used.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @returns The STUN server address being used.
|
||||
* @return The STUN server address being used.
|
||||
* @ingroup network_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_stun_server(const LinphoneCore *lc);
|
||||
|
|
@ -2453,7 +2614,7 @@ LINPHONE_PUBLIC void linphone_core_set_nat_address(LinphoneCore *lc, const char
|
|||
/**
|
||||
* Get the public IP address of NAT being used.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The public IP address of NAT being used.
|
||||
* @return The public IP address of NAT being used.
|
||||
* @ingroup network_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_nat_address(const LinphoneCore *lc);
|
||||
|
|
@ -2469,7 +2630,7 @@ LINPHONE_PUBLIC void linphone_core_set_firewall_policy(LinphoneCore *lc, Linphon
|
|||
/**
|
||||
* Get the policy that is used to pass through firewalls.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The #LinphoneFirewallPolicy that is being used.
|
||||
* @return The #LinphoneFirewallPolicy that is being used.
|
||||
* @ingroup network_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc);
|
||||
|
|
@ -2520,9 +2681,36 @@ LINPHONE_PUBLIC const char *linphone_core_get_root_ca(LinphoneCore *lc);
|
|||
LINPHONE_PUBLIC void linphone_core_set_ringback(LinphoneCore *lc, const char *path);
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_ringback(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_remote_ringback_tone(LinphoneCore *lc,const char *);
|
||||
/**
|
||||
* Specify a ring back tone to be played to far end during incoming calls.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @param[in] ring The path to the ring back tone to be played.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_set_remote_ringback_tone(LinphoneCore *lc, const char *ring);
|
||||
|
||||
/**
|
||||
* Get the ring back tone played to far end during incoming calls.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_remote_ringback_tone(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Enable or disable the ring play during an incoming early media call.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @param[in] enable A boolean value telling whether to enable ringing during an incoming early media call.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_ring_during_incoming_early_media(LinphoneCore *lc, bool_t enable);
|
||||
|
||||
/**
|
||||
* Tells whether the ring play is enabled during an incoming early media call.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @ingroup media_paramaters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_get_ring_during_incoming_early_media(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata);
|
||||
LINPHONE_PUBLIC int linphone_core_play_local(LinphoneCore *lc, const char *audiofile);
|
||||
LINPHONE_PUBLIC void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val);
|
||||
|
|
@ -2539,7 +2727,7 @@ LINPHONE_PUBLIC void linphone_core_enable_echo_limiter(LinphoneCore *lc, bool_t
|
|||
/**
|
||||
* Tells whether echo limiter is enabled.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns TRUE if the echo limiter is enabled, FALSE otherwise.
|
||||
* @return TRUE if the echo limiter is enabled, FALSE otherwise.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_echo_limiter_enabled(const LinphoneCore *lc);
|
||||
|
|
@ -2569,7 +2757,7 @@ LINPHONE_PUBLIC void linphone_core_enable_mic(LinphoneCore *lc, bool_t enable);
|
|||
/**
|
||||
* Tells whether the microphone is enabled.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @returns TRUE if the microphone is enabled, FALSE if disabled.
|
||||
* @return TRUE if the microphone is enabled, FALSE if disabled.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_mic_enabled(LinphoneCore *lc);
|
||||
|
|
@ -2606,7 +2794,7 @@ LINPHONE_PUBLIC void linphone_core_clear_call_logs(LinphoneCore *lc);
|
|||
* Get the number of missed calls.
|
||||
* Once checked, this counter can be reset with linphone_core_reset_missed_calls_count().
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The number of missed calls.
|
||||
* @return The number of missed calls.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_get_missed_calls_count(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -2697,7 +2885,7 @@ LINPHONE_PUBLIC void linphone_core_enable_video_source_reuse(LinphoneCore* lc, b
|
|||
/**
|
||||
* Tells whether video capture is enabled.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns TRUE if video capture is enabled, FALSE if disabled.
|
||||
* @return TRUE if video capture is enabled, FALSE if disabled.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_video_capture_enabled(LinphoneCore *lc);
|
||||
|
|
@ -2705,7 +2893,7 @@ LINPHONE_PUBLIC bool_t linphone_core_video_capture_enabled(LinphoneCore *lc);
|
|||
/**
|
||||
* Tells whether video display is enabled.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns TRUE if video display is enabled, FALSE if disabled.
|
||||
* @return TRUE if video display is enabled, FALSE if disabled.
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_video_display_enabled(LinphoneCore *lc);
|
||||
|
|
@ -2723,12 +2911,13 @@ 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_current_preview_video_size(const 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()).
|
||||
* @return 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);
|
||||
|
|
@ -2768,7 +2957,7 @@ LINPHONE_PUBLIC int linphone_core_set_static_picture(LinphoneCore *lc, const cha
|
|||
/**
|
||||
* Get the path to the image file streamed when "Static picture" is set as the video device.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The path to the image file streamed when "Static picture" is set as the video device.
|
||||
* @return The path to the image file streamed when "Static picture" is set as the video device.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_static_picture(LinphoneCore *lc);
|
||||
|
|
@ -2826,7 +3015,32 @@ void linphone_core_show_video(LinphoneCore *lc, bool_t show);
|
|||
#define linphone_core_use_files(lc, yesno) linphone_core_set_use_files(lc, yesno)
|
||||
/*play/record support: use files instead of soundcard*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno);
|
||||
|
||||
/**
|
||||
* Get the wav file that is played when putting somebody on hold,
|
||||
* or when files are used instead of soundcards (see linphone_core_set_use_files()).
|
||||
*
|
||||
* The file is a 16 bit linear wav file.
|
||||
* @ingroup media_parameters
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @return The path to the file that is played when putting somebody on hold.
|
||||
*/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_play_file(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_play_file(LinphoneCore *lc, const char *file);
|
||||
|
||||
/**
|
||||
* Get the wav file where incoming stream is recorded,
|
||||
* when files are used instead of soundcards (see linphone_core_set_use_files()).
|
||||
*
|
||||
* This feature is different from call recording (linphone_call_params_set_record_file())
|
||||
* The file is a 16 bit linear wav file.
|
||||
* @ingroup media_parameters
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @return The path to the file where incoming stream is recorded.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_record_file(const LinphoneCore *lc);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_set_record_file(LinphoneCore *lc, const char *file);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms);
|
||||
|
|
@ -2925,11 +3139,27 @@ LINPHONE_PUBLIC void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const
|
|||
/**
|
||||
* Get the path to the file storing the zrtp secrets cache.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The path to the file storing the zrtp secrets cache.
|
||||
* @return The path to the file storing the zrtp secrets cache.
|
||||
* @ingroup initializing
|
||||
*/
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Set the path to the directory storing the user's x509 certificates (used by dtls)
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @param[in] path The path to the directory to use to store the user's certificates.
|
||||
* @ingroup initializing
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char* path);
|
||||
|
||||
/**
|
||||
* Get the path to the directory storing the user's certificates.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The path to the directory storing the user's certificates.
|
||||
* @ingroup initializing
|
||||
*/
|
||||
LINPHONE_PUBLIC const char *linphone_core_get_user_certificates_path(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Search from the list of current calls if a remote address match uri
|
||||
* @ingroup call_control
|
||||
|
|
@ -2974,7 +3204,7 @@ LINPHONE_PUBLIC bool_t linphone_core_media_encryption_supported(const LinphoneCo
|
|||
* Choose the media encryption policy to be used for RTP packets.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] menc The media encryption policy to be used.
|
||||
* @returns 0 if successful, any other value otherwise.
|
||||
* @return 0 if successful, any other value otherwise.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_core_set_media_encryption(LinphoneCore *lc, LinphoneMediaEncryption menc);
|
||||
|
|
@ -2982,7 +3212,7 @@ LINPHONE_PUBLIC int linphone_core_set_media_encryption(LinphoneCore *lc, Linphon
|
|||
/**
|
||||
* Get the media encryption policy being used for RTP packets.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The media encryption policy being used.
|
||||
* @return The media encryption policy being used.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneMediaEncryption linphone_core_get_media_encryption(LinphoneCore *lc);
|
||||
|
|
@ -2990,7 +3220,7 @@ LINPHONE_PUBLIC LinphoneMediaEncryption linphone_core_get_media_encryption(Linph
|
|||
/**
|
||||
* Get behaviour when encryption parameters negociation fails on outgoing call.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns TRUE means the call will fail; FALSE means an INVITE will be resent with encryption disabled.
|
||||
* @return TRUE means the call will fail; FALSE means an INVITE will be resent with encryption disabled.
|
||||
* @ingroup media_parameters
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_is_media_encryption_mandatory(LinphoneCore *lc);
|
||||
|
|
@ -3119,6 +3349,7 @@ LINPHONE_PUBLIC void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id,
|
|||
* Globaly set an http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml. This value can also be set for a dedicated account using #linphone_proxy_config_set_file_transfer_server
|
||||
* @param[in] core #LinphoneCore to be modified
|
||||
* @param[in] server_url URL of the file server like https://file.linphone.org/upload.php
|
||||
* @ingroup misc
|
||||
* */
|
||||
LINPHONE_PUBLIC void linphone_core_set_file_transfer_server(LinphoneCore *core, const char * server_url);
|
||||
|
||||
|
|
@ -3126,6 +3357,7 @@ LINPHONE_PUBLIC void linphone_core_set_file_transfer_server(LinphoneCore *core,
|
|||
* Get the globaly set http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml.
|
||||
* @param[in] core #LinphoneCore from which to get the server_url
|
||||
* @return URL of the file server like https://file.linphone.org/upload.php
|
||||
* @ingroup misc
|
||||
* */
|
||||
LINPHONE_PUBLIC const char * linphone_core_get_file_transfer_server(LinphoneCore *core);
|
||||
|
||||
|
|
@ -3149,6 +3381,129 @@ LINPHONE_PUBLIC void linphone_core_set_avpf_rr_interval(LinphoneCore *lc, int in
|
|||
|
||||
LINPHONE_PUBLIC int linphone_core_get_avpf_rr_interval(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Use to set multicast address to be used for audio stream.
|
||||
* @param core #LinphoneCore
|
||||
* @param ip an ipv4/6 multicast address
|
||||
* @return 0 in case of success
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_set_audio_multicast_addr(LinphoneCore *core, const char* ip);
|
||||
/**
|
||||
* Use to set multicast address to be used for video stream.
|
||||
* @param core #LinphoneCore
|
||||
* @param ip an ipv4/6 multicast address
|
||||
* @return 0 in case of success
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_set_video_multicast_addr(LinphoneCore *lc, const char *ip);
|
||||
|
||||
/**
|
||||
* Use to get multicast address to be used for audio stream.
|
||||
* @param core #LinphoneCore
|
||||
* @return an ipv4/6 multicast address or default value
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC const char* linphone_core_get_audio_multicast_addr(const LinphoneCore *core);
|
||||
|
||||
/**
|
||||
* Use to get multicast address to be used for video stream.
|
||||
* @param core #LinphoneCore
|
||||
* @return an ipv4/6 multicast address, or default value
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC const char* linphone_core_get_video_multicast_addr(const LinphoneCore *core);
|
||||
|
||||
/**
|
||||
* Use to set multicast ttl to be used for audio stream.
|
||||
* @param core #LinphoneCore
|
||||
* @param ttl value or -1 if not used. [0..255] default value is 1
|
||||
* @return 0 in case of success
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_set_audio_multicast_ttl(LinphoneCore *core, int ttl);
|
||||
/**
|
||||
* Use to set multicast ttl to be used for video stream.
|
||||
* @param core #LinphoneCore
|
||||
* @param ttl value or -1 if not used. [0..255] default value is 1
|
||||
* @return 0 in case of success
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_set_video_multicast_ttl(LinphoneCore *lc, int ttl);
|
||||
|
||||
/**
|
||||
* Use to get multicast ttl to be used for audio stream.
|
||||
* @param core #LinphoneCore
|
||||
* @return a time to leave value
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_get_audio_multicast_ttl(const LinphoneCore *core);
|
||||
|
||||
/**
|
||||
* Use to get multicast ttl to be used for video stream.
|
||||
* @param core #LinphoneCore
|
||||
* @return a time to leave value
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_get_video_multicast_ttl(const LinphoneCore *core);
|
||||
|
||||
|
||||
/**
|
||||
* Use to enable multicast rtp for audio stream.
|
||||
* * If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into audio cline. In case of outgoing call audio stream is sent to this multicast address.
|
||||
* <br> For incoming calls behavior is unchanged.
|
||||
* @param core #LinphoneCore
|
||||
* @param yesno if yes, subsequent calls will propose multicast ip set by #linphone_core_set_audio_multicast_addr
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_enable_audio_multicast(LinphoneCore *core, bool_t yesno);
|
||||
|
||||
/**
|
||||
* Use to get multicast state of audio stream.
|
||||
* @param core #LinphoneCore
|
||||
* @return true if subsequent calls will propose multicast ip set by #linphone_core_set_audio_multicast_addr
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_audio_multicast_enabled(const LinphoneCore *core);
|
||||
|
||||
/**
|
||||
* Use to enable multicast rtp for video stream.
|
||||
* If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into video cline. In case of outgoing call video stream is sent to this multicast address.
|
||||
* <br> For incoming calls behavior is unchanged.
|
||||
* @param core #LinphoneCore
|
||||
* @param yesno if yes, subsequent outgoing calls will propose multicast ip set by #linphone_core_set_video_multicast_addr
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_enable_video_multicast(LinphoneCore *core, bool_t yesno);
|
||||
/**
|
||||
* Use to get multicast state of video stream.
|
||||
* @param core #LinphoneCore
|
||||
* @return true if subsequent calls will propose multicast ip set by #linphone_core_set_video_multicast_addr
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_core_video_multicast_enabled(const LinphoneCore *core);
|
||||
|
||||
/**
|
||||
* Set the network simulator parameters.
|
||||
* Liblinphone has the capabability of simulating the effects of a network (latency, lost packets, jitter, max bandwidth).
|
||||
* Please refer to the oRTP documentation for the meaning of the parameters of the OrtpNetworkSimulatorParams structure.
|
||||
* This function has effect for future calls, but not for currently running calls, though this behavior may be changed in future versions.
|
||||
* @warning Due to design of network simulation in oRTP, simulation is applied independently for audio and video stream. This means for example that a bandwidth
|
||||
* limit of 250kbit/s will have no effect on an audio stream running at 40kbit/s while a videostream targetting 400kbit/s will be highly affected.
|
||||
* @param lc the LinphoneCore
|
||||
* @param params the parameters used for the network simulation.
|
||||
* @return 0 if successful, -1 otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC int linphone_core_set_network_simulator_params(LinphoneCore *lc, const OrtpNetworkSimulatorParams *params);
|
||||
|
||||
|
||||
/**
|
||||
* Get the previously set network simulation parameters.
|
||||
* @see linphone_core_set_network_simulator_params
|
||||
* @return a OrtpNetworkSimulatorParams structure.
|
||||
**/
|
||||
LINPHONE_PUBLIC const OrtpNetworkSimulatorParams *linphone_core_get_network_simulator_params(const LinphoneCore *lc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -261,14 +261,14 @@ LINPHONE_PUBLIC void linphone_friend_set_ref_key(LinphoneFriend *lf, const char
|
|||
/**
|
||||
* Get the reference key of a friend.
|
||||
* @param[in] lf #LinphoneFriend object.
|
||||
* @returns The reference key of the friend.
|
||||
* @return The reference key of the friend.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_friend_get_ref_key(const LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Check that the given friend is in a friend list.
|
||||
* @param[in] lf #LinphoneFriend object.
|
||||
* @returns TRUE if the friend is in a friend list, FALSE otherwise.
|
||||
* @return TRUE if the friend is in a friend list, FALSE otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_friend_in_list(const LinphoneFriend *lf);
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ LINPHONE_PUBLIC void linphone_core_notify_all_friends(LinphoneCore *lc, Linphone
|
|||
* Search a LinphoneFriend by its address.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] addr The address to use to search the friend.
|
||||
* @returns The #LinphoneFriend object corresponding to the given address.
|
||||
* @return The #LinphoneFriend object corresponding to the given address.
|
||||
* @deprecated use linphone_core_find_friend() instead.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *addr);
|
||||
|
|
@ -381,7 +381,7 @@ LINPHONE_PUBLIC LinphoneFriend *linphone_core_get_friend_by_address(const Linpho
|
|||
* Search a LinphoneFriend by its address.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] addr The address to use to search the friend.
|
||||
* @returns The #LinphoneFriend object corresponding to the given address.
|
||||
* @return The #LinphoneFriend object corresponding to the given address.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr);
|
||||
|
||||
|
|
@ -389,7 +389,7 @@ LINPHONE_PUBLIC LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc
|
|||
* Search a LinphoneFriend by its reference key.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] key The reference key to use to search the friend.
|
||||
* @returns The #LinphoneFriend object corresponding to the given reference key.
|
||||
* @return The #LinphoneFriend object corresponding to the given reference key.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key);
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ typedef struct _LinphonePresenceNote LinphonePresenceNote;
|
|||
* Creates a presence model specifying an activity.
|
||||
* @param[in] activity The activity to set for the created presence model.
|
||||
* @param[in] description An additional description of the activity (mainly useful for the 'other' activity). Set it to NULL to not add a description.
|
||||
* @returns The created presence model, or NULL if an error occured.
|
||||
* @return The created presence model, or NULL if an error occured.
|
||||
* @see linphone_presence_model_new
|
||||
* @see linphone_presence_model_new_with_activity_and_note
|
||||
*
|
||||
|
|
@ -214,7 +214,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new_with_activit
|
|||
* @param[in] description An additional description of the activity (mainly useful for the 'other' activity). Set it to NULL to not add a description.
|
||||
* @param[in] note An additional note giving additional information about the contact presence.
|
||||
* @param[in] lang The language the note is written in. It can be set to NULL in order to not specify the language of the note.
|
||||
* @returns The created presence model, or NULL if an error occured.
|
||||
* @return The created presence model, or NULL if an error occured.
|
||||
* @see linphone_presence_model_new_with_activity
|
||||
* @see linphone_presence_model_new_with_activity_and_note
|
||||
*
|
||||
|
|
@ -344,7 +344,7 @@ LINPHONE_PUBLIC int linphone_presence_model_clear_notes(LinphonePresenceModel *m
|
|||
|
||||
/**
|
||||
* Creates a default presence model.
|
||||
* @returns The created presence model, NULL on error.
|
||||
* @return The created presence model, NULL on error.
|
||||
* @see linphone_presence_model_new_with_activity
|
||||
* @see linphone_presence_model_new_with_activity_and_note
|
||||
*
|
||||
|
|
@ -422,7 +422,7 @@ LINPHONE_PUBLIC int linphone_presence_model_clear_persons(LinphonePresenceModel
|
|||
* @param[in] id The id of the presence service to be created. Can be NULL to generate it automatically.
|
||||
* @param[in] basic_status The #LinphonePresenceBasicStatus to set for the #LinphonePresenceService object.
|
||||
* @param[in] contact The contact string to set.
|
||||
* @returns The created presence service, NULL on error.
|
||||
* @return The created presence service, NULL on error.
|
||||
*
|
||||
* The created presence service has the basic status 'closed'.
|
||||
*/
|
||||
|
|
@ -515,7 +515,7 @@ LINPHONE_PUBLIC int linphone_presence_service_clear_notes(LinphonePresenceServic
|
|||
/**
|
||||
* Creates a presence person.
|
||||
* @param[in] id The id of the presence person to be created. Can be NULL to generate it automatically.
|
||||
* @returns The created presence person, NULL on error.
|
||||
* @return The created presence person, NULL on error.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresencePerson * linphone_presence_person_new(const char *id);
|
||||
|
||||
|
|
@ -635,7 +635,7 @@ LINPHONE_PUBLIC int linphone_presence_person_clear_activities_notes(LinphonePres
|
|||
* Creates a presence activity.
|
||||
* @param[in] acttype The #LinphonePresenceActivityType to set for the activity.
|
||||
* @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added.
|
||||
* @returns The created presence activity, NULL on error.
|
||||
* @return The created presence activity, NULL on error.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceActivity * linphone_presence_activity_new(LinphonePresenceActivityType acttype, const char *description);
|
||||
|
||||
|
|
@ -687,7 +687,7 @@ LINPHONE_PUBLIC int linphone_presence_activity_set_description(LinphonePresenceA
|
|||
* Creates a presence note.
|
||||
* @param[in] content The content of the note to be created.
|
||||
* @param[in] lang The language of the note to be created. Can be NULL if no language is to be specified for the note.
|
||||
* @returns The created presence note, NULL on error.
|
||||
* @return The created presence note, NULL on error.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceNote * linphone_presence_note_new(const char *content, const char *lang);
|
||||
|
||||
|
|
@ -876,14 +876,14 @@ LINPHONE_PUBLIC void * linphone_presence_note_get_user_data(const LinphonePresen
|
|||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] acttype The #LinphonePresenceActivityType to set for the activity.
|
||||
* @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added.
|
||||
* @returns The created #LinphonePresenceActivity object.
|
||||
* @return The created #LinphonePresenceActivity object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceActivity * linphone_core_create_presence_activity(LinphoneCore *lc, LinphonePresenceActivityType acttype, const char *description);
|
||||
|
||||
/**
|
||||
* Create a default LinphonePresenceModel.
|
||||
* @param[in] lc #LinphoneCore object.
|
||||
* @returns The created #LinphonePresenceModel object.
|
||||
* @return The created #LinphonePresenceModel object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -892,7 +892,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model(Linp
|
|||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] acttype The #LinphonePresenceActivityType to set for the activity of the created model.
|
||||
* @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added.
|
||||
* @returns The created #LinphonePresenceModel object.
|
||||
* @return The created #LinphonePresenceModel object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with_activity(LinphoneCore *lc, LinphonePresenceActivityType acttype, const char *description);
|
||||
|
||||
|
|
@ -903,7 +903,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with
|
|||
* @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added.
|
||||
* @param[in] note The content of the note to be added to the created model.
|
||||
* @param[in] lang The language of the note to be added to the created model.
|
||||
* @returns The created #LinphonePresenceModel object.
|
||||
* @return The created #LinphonePresenceModel object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with_activity_and_note(LinphoneCore *lc, LinphonePresenceActivityType acttype, const char *description, const char *note, const char *lang);
|
||||
|
||||
|
|
@ -912,7 +912,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with
|
|||
* @param[in] lc #LinphoneCore object.
|
||||
* @param[in] content The content of the note to be created.
|
||||
* @param[in] lang The language of the note to be created.
|
||||
* @returns The created #LinphonePresenceNote object.
|
||||
* @return The created #LinphonePresenceNote object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceNote * linphone_core_create_presence_note(LinphoneCore *lc, const char *content, const char *lang);
|
||||
|
||||
|
|
@ -920,7 +920,7 @@ LINPHONE_PUBLIC LinphonePresenceNote * linphone_core_create_presence_note(Linpho
|
|||
* Create a LinphonePresencePerson with the given id.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @param[in] id The id of the person to be created.
|
||||
* @returns The created #LinphonePresencePerson object.
|
||||
* @return The created #LinphonePresencePerson object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresencePerson * linphone_core_create_presence_person(LinphoneCore *lc, const char *id);
|
||||
|
||||
|
|
@ -930,7 +930,7 @@ LINPHONE_PUBLIC LinphonePresencePerson * linphone_core_create_presence_person(Li
|
|||
* @param[in] id The id of the service to be created.
|
||||
* @param[in] basic_status The basic status of the service to be created.
|
||||
* @param[in] contact A string containing a contact information corresponding to the service to be created.
|
||||
* @returns The created #LinphonePresenceService object.
|
||||
* @return The created #LinphonePresenceService object.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphonePresenceService * linphone_core_create_presence_service(LinphoneCore *lc, const char *id, LinphonePresenceBasicStatus basic_status, const char *contact);
|
||||
|
||||
|
|
|
|||
|
|
@ -734,25 +734,26 @@ void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filenam
|
|||
}
|
||||
}
|
||||
|
||||
char *lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename) {
|
||||
int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename, char *data, size_t max_length) {
|
||||
char *dir = _lp_config_dirname(lpconfig->filename);
|
||||
char *filepath = ms_strdup_printf("%s/%s", dir, filename);
|
||||
char *result = NULL;
|
||||
if(ortp_file_exist(filepath) == 0) {
|
||||
FILE *file = fopen(filepath, "r");
|
||||
if(file != NULL) {
|
||||
result = ms_new0(char, MAX_LEN);
|
||||
if(fgets(result, MAX_LEN, file) == NULL) {
|
||||
ms_error("%s could not be loaded", filepath);
|
||||
}
|
||||
fclose(file);
|
||||
} else {
|
||||
ms_error("Could not open %s for read", filepath);
|
||||
FILE *file = fopen(filepath, "r");
|
||||
if(file != NULL) {
|
||||
if(fread(data, 1, max_length, file)<=0) {
|
||||
ms_error("%s could not be loaded. %s", filepath, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
fclose(file);
|
||||
} else {
|
||||
ms_message("%s does not exist", filepath);
|
||||
ms_error("Could not open %s for read. %s", filepath, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
ms_free(dir);
|
||||
ms_free(filepath);
|
||||
return result;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
ms_free(dir);
|
||||
ms_free(filepath);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,12 +281,14 @@ LINPHONE_PUBLIC void lp_config_unref(LpConfig *lpconfig);
|
|||
LINPHONE_PUBLIC void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data);
|
||||
|
||||
/**
|
||||
* @brief Read a string from a file placed relatively with the Linphone configuration file
|
||||
* @brief Read a string from a file placed beside the Linphone configuration file
|
||||
* @param lpconfig LpConfig instance used as a reference
|
||||
* @param filename Name of the file where data will be read from. The name is relative to the place of the config file
|
||||
* @return The read string
|
||||
* @param data Buffer where read string will be stored
|
||||
* @param max_length Length of the buffer
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
LINPHONE_PUBLIC char *lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename);
|
||||
LINPHONE_PUBLIC int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename, char *data, size_t max_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,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;
|
||||
}
|
||||
|
|
@ -199,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);
|
||||
|
|
@ -240,7 +237,7 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
|
|||
(int64_t)msg->time,
|
||||
msg->appdata,
|
||||
content_id
|
||||
);
|
||||
);
|
||||
linphone_sql_request(lc->db,buf);
|
||||
sqlite3_free(buf);
|
||||
ms_free(local_contact);
|
||||
|
|
@ -258,13 +255,6 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg){
|
|||
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){
|
||||
|
|
@ -381,7 +371,7 @@ MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, i
|
|||
|
||||
if (startm<0) startm=0;
|
||||
|
||||
if (endm>0&&endm>=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;
|
||||
|
|
@ -601,6 +591,7 @@ void linphone_core_message_storage_init(LinphoneCore *lc){
|
|||
errmsg=sqlite3_errmsg(db);
|
||||
ms_error("Error in the opening: %s.\n", errmsg);
|
||||
sqlite3_close(db);
|
||||
return;
|
||||
}
|
||||
|
||||
linphone_message_storage_activate_debug(db, lc->debug_storage);
|
||||
|
|
|
|||
107
coreapi/misc.c
107
coreapi/misc.c
|
|
@ -41,7 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif /*_WIN32_WCE*/
|
||||
|
||||
#undef snprintf
|
||||
#include <ortp/stun.h>
|
||||
#include <mediastreamer2/stun.h>
|
||||
|
||||
#ifdef HAVE_GETIFADDRS
|
||||
#include <net/if.h>
|
||||
|
|
@ -59,15 +59,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define RTP_HDR_SZ 12
|
||||
#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/
|
||||
|
||||
static void payload_type_set_enable(PayloadType *pt,int value)
|
||||
{
|
||||
if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \
|
||||
else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED);
|
||||
}
|
||||
|
||||
static bool_t payload_type_enabled(const PayloadType *pt) {
|
||||
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
|
||||
}
|
||||
|
||||
bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){
|
||||
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){
|
||||
|
|
@ -97,6 +88,10 @@ int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *p
|
|||
return payload_type_get_number(pt);
|
||||
}
|
||||
|
||||
void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number){
|
||||
payload_type_set_number(pt,number);
|
||||
}
|
||||
|
||||
const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt){
|
||||
if (ms_filter_codec_supported(pt->mime_type)){
|
||||
MSFilterDesc *desc=ms_filter_get_encoder(pt->mime_type);
|
||||
|
|
@ -177,7 +172,7 @@ static int lookup_vbr_typical_bitrate(int maxbw, int clock_rate){
|
|||
static int get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *pt, int maxbw){
|
||||
if (linphone_core_payload_type_is_vbr(lc,pt)){
|
||||
if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE){
|
||||
ms_message("PayloadType %s/%i has bitrate override",pt->mime_type,pt->clock_rate);
|
||||
ms_debug("PayloadType %s/%i has bitrate override",pt->mime_type,pt->clock_rate);
|
||||
return pt->normal_bitrate/1000;
|
||||
}
|
||||
return lookup_vbr_typical_bitrate(maxbw,pt->clock_rate);
|
||||
|
|
@ -641,6 +636,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;
|
||||
|
|
@ -699,6 +712,8 @@ 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 _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
|
||||
|
|
@ -825,8 +840,25 @@ static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed){
|
|||
void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md)
|
||||
{
|
||||
bool_t ice_restarted = FALSE;
|
||||
|
||||
if ((md->ice_pwd[0] != '\0') && (md->ice_ufrag[0] != '\0')) {
|
||||
bool_t ice_params_found=FALSE;
|
||||
if ((md->ice_pwd[0] != '\0') && (md->ice_ufrag[0] != '\0')) {
|
||||
ice_params_found=TRUE;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
const SalStreamDescription *stream = &md->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (cl) {
|
||||
if ((stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) {
|
||||
ice_params_found=TRUE;
|
||||
} else {
|
||||
ice_params_found=FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ice_params_found) {
|
||||
int i, j;
|
||||
|
||||
/* Check for ICE restart and set remote credentials. */
|
||||
|
|
@ -858,11 +890,14 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call,
|
|||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (cl && (stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) {
|
||||
if (ice_check_list_remote_credentials_changed(cl, stream->ice_ufrag, stream->ice_pwd)) {
|
||||
if (ice_restarted == FALSE) {
|
||||
if (ice_restarted == FALSE
|
||||
&& ice_check_list_get_remote_ufrag(cl)
|
||||
&& ice_check_list_get_remote_pwd(cl)) {
|
||||
/* restart onlu if remote ufrag/paswd was already set*/
|
||||
ice_session_restart(call->ice_session);
|
||||
ice_restarted = TRUE;
|
||||
}
|
||||
ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd);
|
||||
ice_check_list_set_remote_credentials(cl, stream->ice_ufrag, stream->ice_pwd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1409,7 +1444,7 @@ static void linphone_core_migrate_proxy_config(LinphoneCore *lc, LinphoneTranspo
|
|||
* Existing proxy configuration are added a transport parameter so that they continue using the unique transport that was set previously.
|
||||
* This function must be used just after creating the core, before any call to linphone_core_iterate()
|
||||
* @param lc the linphone core
|
||||
* @returns 1 if migration was done, 0 if not done because unnecessary or already done, -1 in case of error.
|
||||
* @return 1 if migration was done, 0 if not done because unnecessary or already done, -1 in case of error.
|
||||
* @ingroup initializing
|
||||
**/
|
||||
int linphone_core_migrate_to_multi_transport(LinphoneCore *lc){
|
||||
|
|
@ -1565,3 +1600,43 @@ bool_t linphone_core_symmetric_rtp_enabled(LinphoneCore*lc){
|
|||
return lp_config_get_int(lc->config,"rtp","symmetric",1);
|
||||
}
|
||||
|
||||
int linphone_core_set_network_simulator_params(LinphoneCore *lc, const OrtpNetworkSimulatorParams *params){
|
||||
if (params!=&lc->net_conf.netsim_params)
|
||||
lc->net_conf.netsim_params=*params;
|
||||
/*TODO: should we make some sanity checks on the parameters here*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OrtpNetworkSimulatorParams *linphone_core_get_network_simulator_params(const LinphoneCore *lc){
|
||||
return &lc->net_conf.netsim_params;
|
||||
}
|
||||
|
||||
static const char *_tunnel_mode_str[3] = { "disable", "enable", "auto" };
|
||||
|
||||
LinphoneTunnelMode linphone_tunnel_mode_from_string(const char *string) {
|
||||
if(string != NULL) {
|
||||
int i;
|
||||
for(i=0; i<3 && strcmp(string, _tunnel_mode_str[i]) != 0; i++);
|
||||
if(i<3) {
|
||||
return (LinphoneTunnelMode)i;
|
||||
} else {
|
||||
ms_error("Invalid tunnel mode '%s'", string);
|
||||
return LinphoneTunnelModeDisable;
|
||||
}
|
||||
} else {
|
||||
return LinphoneTunnelModeDisable;
|
||||
}
|
||||
}
|
||||
|
||||
const char *linphone_tunnel_mode_to_string(LinphoneTunnelMode mode) {
|
||||
switch(mode){
|
||||
case LinphoneTunnelModeAuto:
|
||||
return "auto";
|
||||
case LinphoneTunnelModeDisable:
|
||||
return "disable";
|
||||
case LinphoneTunnelModeEnable:
|
||||
return "enable";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,49 @@ static bool_t only_telephone_event(const MSList *l){
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
|
||||
typedef struct _PayloadTypeMatcher{
|
||||
const char *mime_type;
|
||||
PayloadType *(*match_func)(const MSList *l, const PayloadType *refpt);
|
||||
}PayloadTypeMatcher;
|
||||
|
||||
static PayloadType * opus_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
/*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/
|
||||
if (strcasecmp(pt->mime_type,"opus")==0 ){
|
||||
if (refpt->channels==1){
|
||||
pt->channels=1; /*so that we respond with same number of channels */
|
||||
candidate=pt;
|
||||
}else if (refpt->channels==2){
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
/* the reason for this matcher is for some stupid uncompliant phone that offer G729a mime type !*/
|
||||
static PayloadType * g729A_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
PayloadType *candidate=NULL;
|
||||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
if (strcasecmp(pt->mime_type,"G729")==0 && refpt->channels==pt->channels){
|
||||
candidate=pt;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static PayloadType * amr_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
char value[10];
|
||||
const MSList *elem;
|
||||
|
|
@ -40,39 +82,65 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload
|
|||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
/*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/
|
||||
if (refpt->mime_type && strcasecmp(refpt->mime_type,"opus")==0 && refpt->channels==1
|
||||
&& strcasecmp(pt->mime_type,refpt->mime_type)==0){
|
||||
pt->channels=1; /*so that we respond with same number of channels */
|
||||
candidate=pt;
|
||||
break;
|
||||
}
|
||||
|
||||
/* the compare between G729 and G729A is for some stupid uncompliant phone*/
|
||||
if ( pt->mime_type && refpt->mime_type &&
|
||||
(strcasecmp(pt->mime_type,refpt->mime_type)==0 ||
|
||||
(strcasecmp(pt->mime_type, "G729") == 0 && strcasecmp(refpt->mime_type, "G729A") == 0 ))
|
||||
&& pt->clock_rate==refpt->clock_rate && pt->channels==refpt->channels){
|
||||
candidate=pt;
|
||||
/*good candidate, check fmtp for H264 */
|
||||
if (strcasecmp(pt->mime_type,"H264")==0){
|
||||
if (pt->recv_fmtp!=NULL && refpt->recv_fmtp!=NULL){
|
||||
int mode1=0,mode2=0;
|
||||
if (fmtp_get_value(pt->recv_fmtp,"packetization-mode",value,sizeof(value))){
|
||||
mode1=atoi(value);
|
||||
}
|
||||
if (fmtp_get_value(refpt->recv_fmtp,"packetization-mode",value,sizeof(value))){
|
||||
mode2=atoi(value);
|
||||
}
|
||||
if (mode1==mode2)
|
||||
break; /*exact match */
|
||||
}
|
||||
}else break;
|
||||
if ( pt->mime_type && refpt->mime_type
|
||||
&& strcasecmp(pt->mime_type, refpt->mime_type)==0
|
||||
&& pt->clock_rate==refpt->clock_rate
|
||||
&& pt->channels==refpt->channels) {
|
||||
int octedalign1=0,octedalign2=0;
|
||||
if (pt->recv_fmtp!=NULL && fmtp_get_value(pt->recv_fmtp,"octet-align",value,sizeof(value))){
|
||||
octedalign1=atoi(value);
|
||||
}
|
||||
if (refpt->send_fmtp!=NULL && fmtp_get_value(refpt->send_fmtp,"octet-align",value,sizeof(value))){
|
||||
octedalign2=atoi(value);
|
||||
}
|
||||
if (octedalign1==octedalign2) {
|
||||
candidate=pt;
|
||||
break; /*exact match */
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static PayloadType * generic_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
const MSList *elem;
|
||||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
|
||||
if ( pt->mime_type && refpt->mime_type
|
||||
&& strcasecmp(pt->mime_type, refpt->mime_type)==0
|
||||
&& pt->clock_rate==refpt->clock_rate
|
||||
&& pt->channels==refpt->channels)
|
||||
return pt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PayloadTypeMatcher matchers[]={
|
||||
{"opus", opus_match},
|
||||
{"G729A", g729A_match},
|
||||
{"AMR", amr_match},
|
||||
{"AMR-WB", amr_match},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list
|
||||
*/
|
||||
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadTypeMatcher *m;
|
||||
for(m=matchers;m->mime_type!=NULL;++m){
|
||||
if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){
|
||||
return m->match_func(l,refpt);
|
||||
}
|
||||
}
|
||||
return generic_match(l,refpt);
|
||||
}
|
||||
|
||||
|
||||
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
|
||||
const MSList *e2,*e1;
|
||||
MSList *res=NULL;
|
||||
|
|
@ -96,8 +164,9 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
}
|
||||
|
||||
newp=payload_type_clone(matched);
|
||||
if (p2->send_fmtp)
|
||||
payload_type_set_send_fmtp(newp,p2->send_fmtp);
|
||||
if (p2->send_fmtp){
|
||||
payload_type_append_send_fmtp(newp,p2->send_fmtp);
|
||||
}
|
||||
newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND;
|
||||
if (p2->flags & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) {
|
||||
newp->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED;
|
||||
|
|
@ -110,6 +179,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
res=ms_list_append(res,newp);
|
||||
/* we should use the remote numbering even when parsing a response */
|
||||
payload_type_set_number(newp,remote_number);
|
||||
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
if (reading_response && remote_number!=local_number){
|
||||
ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i",
|
||||
newp->mime_type, local_number, remote_number);
|
||||
|
|
@ -120,6 +190,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
*/
|
||||
newp=payload_type_clone(newp);
|
||||
payload_type_set_number(newp,local_number);
|
||||
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
res=ms_list_append(res,newp);
|
||||
}
|
||||
}else{
|
||||
|
|
@ -143,7 +214,8 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
if (!found){
|
||||
ms_message("Adding %s/%i for compatibility, just in case.",p1->mime_type,p1->clock_rate);
|
||||
p1=payload_type_clone(p1);
|
||||
p1->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV;
|
||||
payload_type_set_flag(p1, PAYLOAD_TYPE_FLAG_CAN_RECV);
|
||||
payload_type_set_flag(p1, PAYLOAD_TYPE_FROZEN_NUMBER);
|
||||
res=ms_list_append(res,p1);
|
||||
}
|
||||
}
|
||||
|
|
@ -227,9 +299,81 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
SalStreamDescription *result){
|
||||
if (remote_answer->rtp_port!=0)
|
||||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
|
||||
else {
|
||||
ms_message("Local stream description [%p] rejected by peer",local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
result->proto=remote_answer->proto;
|
||||
result->type=local_offer->type;
|
||||
result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
|
||||
|
||||
if (local_offer->rtp_addr[0]!='\0' && ms_is_multicast(local_offer->rtp_addr)) {
|
||||
/*6.2 Multicast Streams
|
||||
...
|
||||
If a multicast stream is accepted, the address and port information
|
||||
in the answer MUST match that of the offer. Similarly, the
|
||||
directionality information in the answer (sendonly, recvonly, or
|
||||
sendrecv) MUST equal that of the offer. This is because all
|
||||
participants in a multicast session need to have equivalent views of
|
||||
the parameters of the session, an underlying assumption of the
|
||||
multicast bias of RFC 2327.*/
|
||||
if (strcmp(local_offer->rtp_addr,remote_answer->rtp_addr) !=0 ) {
|
||||
ms_message("Remote answered IP [%s] does not match offered [%s] for local stream description [%p]"
|
||||
,remote_answer->rtp_addr
|
||||
,local_offer->rtp_addr
|
||||
,local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
if (local_offer->rtp_port!=remote_answer->rtp_port) {
|
||||
ms_message("Remote answered rtp port [%i] does not match offered [%i] for local stream description [%p]"
|
||||
,remote_answer->rtp_port
|
||||
,local_offer->rtp_port
|
||||
,local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
if (local_offer->dir!=remote_answer->dir) {
|
||||
ms_message("Remote answered dir [%s] does not match offered [%s] for local stream description [%p]"
|
||||
,sal_stream_dir_to_string(remote_answer->dir)
|
||||
,sal_stream_dir_to_string(local_offer->dir)
|
||||
,local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
if (local_offer->bandwidth!=remote_answer->bandwidth) {
|
||||
ms_message("Remote answered bandwidth [%i] does not match offered [%i] for local stream description [%p]"
|
||||
,remote_answer->bandwidth
|
||||
,local_offer->bandwidth
|
||||
,local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
if (local_offer->ptime > 0 && local_offer->ptime!=remote_answer->ptime) {
|
||||
ms_message("Remote answered ptime [%i] does not match offered [%i] for local stream description [%p]"
|
||||
,remote_answer->ptime
|
||||
,local_offer->ptime
|
||||
,local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
if (local_offer->ttl > 0 && local_offer->ttl!=remote_answer->ttl) {
|
||||
ms_message("Remote answered ttl [%i] does not match offered [%i] for local stream description [%p]"
|
||||
,remote_answer->ttl
|
||||
,local_offer->ttl
|
||||
,local_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
result->ttl=local_offer->ttl;
|
||||
result->dir=local_offer->dir;
|
||||
result->multicast_role = SalMulticastSender;
|
||||
|
||||
} else {
|
||||
result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->rtp_addr,remote_answer->rtp_addr);
|
||||
|
|
@ -247,6 +391,24 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE))
|
||||
result->rtp_port = 0;
|
||||
}
|
||||
result->rtp_ssrc=local_offer->rtp_ssrc;
|
||||
strncpy(result->rtcp_cname,local_offer->rtcp_cname,sizeof(result->rtcp_cname));
|
||||
|
||||
// Handle dtls session attribute: if both local and remote have a dtls fingerprint and a dtls setup, get the remote fingerprint into the result
|
||||
if ((local_offer->dtls_role!=SalDtlsRoleInvalid) && (remote_answer->dtls_role!=SalDtlsRoleInvalid)
|
||||
&&(strlen(local_offer->dtls_fingerprint)>0) && (strlen(remote_answer->dtls_fingerprint)>0)) {
|
||||
strncpy(result->dtls_fingerprint, remote_answer->dtls_fingerprint,sizeof(result->dtls_fingerprint));
|
||||
if (remote_answer->dtls_role==SalDtlsRoleIsClient) {
|
||||
result->dtls_role = SalDtlsRoleIsServer;
|
||||
} else {
|
||||
result->dtls_role = SalDtlsRoleIsClient;
|
||||
}
|
||||
} else {
|
||||
result->dtls_fingerprint[0] = '\0';
|
||||
result->dtls_role = SalDtlsRoleInvalid;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -257,15 +419,33 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
|
|||
result->proto=remote_offer->proto;
|
||||
result->type=local_cap->type;
|
||||
result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
|
||||
if (result->payloads && !only_telephone_event(result->payloads) && (remote_offer->rtp_port!=0 || remote_offer->rtp_port==SalStreamSendOnly)){
|
||||
if (!result->payloads || only_telephone_event(result->payloads) || remote_offer->rtp_port==0 || remote_offer->dir==SalStreamRecvOnly){
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
if (remote_offer->rtp_addr[0]!='\0' && ms_is_multicast(remote_offer->rtp_addr)) {
|
||||
if (sal_stream_description_has_srtp(result) == TRUE) {
|
||||
ms_message("SAVP not supported for multicast address for remote stream [%p]",remote_offer);
|
||||
result->rtp_port=0;
|
||||
return;
|
||||
}
|
||||
result->dir=remote_offer->dir;
|
||||
strcpy(result->rtp_addr,remote_offer->rtp_addr);
|
||||
strcpy(result->rtcp_addr,remote_offer->rtcp_addr);
|
||||
result->rtp_port=remote_offer->rtp_port;
|
||||
/*result->rtcp_port=remote_offer->rtcp_port;*/
|
||||
result->rtcp_port=0; /* rtcp not supported yet*/
|
||||
result->bandwidth=remote_offer->bandwidth;
|
||||
result->ptime=remote_offer->ptime;
|
||||
result->ttl=remote_offer->ttl;
|
||||
result->multicast_role = SalMulticastReceiver;
|
||||
} else {
|
||||
strcpy(result->rtp_addr,local_cap->rtp_addr);
|
||||
strcpy(result->rtcp_addr,local_cap->rtcp_addr);
|
||||
result->rtp_port=local_cap->rtp_port;
|
||||
result->rtcp_port=local_cap->rtcp_port;
|
||||
result->bandwidth=local_cap->bandwidth;
|
||||
result->ptime=local_cap->ptime;
|
||||
}else{
|
||||
result->rtp_port=0;
|
||||
}
|
||||
if (sal_stream_description_has_srtp(result) == TRUE) {
|
||||
/* select crypto algo */
|
||||
|
|
@ -281,8 +461,26 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
|
|||
memcpy(result->ice_candidates, local_cap->ice_candidates, sizeof(result->ice_candidates));
|
||||
memcpy(result->ice_remote_candidates, local_cap->ice_remote_candidates, sizeof(result->ice_remote_candidates));
|
||||
strcpy(result->name,local_cap->name);
|
||||
result->rtp_ssrc=local_cap->rtp_ssrc;
|
||||
strncpy(result->rtcp_cname,local_cap->rtcp_cname,sizeof(result->rtcp_cname));
|
||||
|
||||
// Handle dtls stream attribute: if both local and remote have a dtls fingerprint and a dtls setup, add the local fingerprint to the answer
|
||||
// Note: local description usually stores dtls config at session level which means it apply to all streams, check this too
|
||||
if (((local_cap->dtls_role!=SalDtlsRoleInvalid)) && (remote_offer->dtls_role!=SalDtlsRoleInvalid)
|
||||
&& (strlen(local_cap->dtls_fingerprint)>0) && (strlen(remote_offer->dtls_fingerprint)>0)) {
|
||||
strncpy(result->dtls_fingerprint, local_cap->dtls_fingerprint,sizeof(result->dtls_fingerprint));
|
||||
if (remote_offer->dtls_role==SalDtlsRoleUnset) {
|
||||
result->dtls_role = SalDtlsRoleIsClient;
|
||||
}
|
||||
} else {
|
||||
result->dtls_fingerprint[0] = '\0';
|
||||
result->dtls_role = SalDtlsRoleInvalid;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a media description to run the streams with, based on a local offer
|
||||
* and the returned response (remote).
|
||||
|
|
@ -334,7 +532,9 @@ static bool_t local_stream_not_already_used(const SalMediaDescription *result, c
|
|||
static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) {
|
||||
if (local == remote) return TRUE;
|
||||
if ((remote == SalProtoRtpAvp) && ((local == SalProtoRtpSavp) || (local == SalProtoRtpSavpf))) return TRUE;
|
||||
if ((remote == SalProtoRtpAvp) && ((local == SalProtoUdpTlsRtpSavp) || (local == SalProtoUdpTlsRtpSavpf))) return TRUE;
|
||||
if ((remote == SalProtoRtpAvpf) && (local == SalProtoRtpSavpf)) return TRUE;
|
||||
if ((remote == SalProtoRtpAvpf) && (local == SalProtoUdpTlsRtpSavpf)) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +567,6 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
}else ms_warning("Unknown protocol for mline %i, declining",i);
|
||||
if (ls){
|
||||
initiate_incoming(ls,rs,&result->streams[i],one_matching_codec);
|
||||
|
||||
// Handle media RTCP XR attribute
|
||||
memset(&result->streams[i].rtcp_xr, 0, sizeof(result->streams[i].rtcp_xr));
|
||||
if (rs->rtcp_xr.enabled == TRUE) {
|
||||
|
|
|
|||
|
|
@ -1211,19 +1211,15 @@ static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, Lin
|
|||
service_id_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
service = presence_service_new(service_id_str, basic_status);
|
||||
if (service != NULL) {
|
||||
if (timestamp_str != NULL) {
|
||||
presence_service_set_timestamp(service, parse_timestamp(timestamp_str));
|
||||
linphone_free_xml_text_content(timestamp_str);
|
||||
}
|
||||
if (contact_str != NULL) {
|
||||
linphone_presence_service_set_contact(service, contact_str);
|
||||
linphone_free_xml_text_content(contact_str);
|
||||
}
|
||||
if (timestamp_str != NULL) presence_service_set_timestamp(service, parse_timestamp(timestamp_str));
|
||||
if (contact_str != NULL) linphone_presence_service_set_contact(service, contact_str);
|
||||
process_pidf_xml_presence_service_notes(xml_ctx, service, i);
|
||||
linphone_presence_model_add_service(model, service);
|
||||
}
|
||||
linphone_free_xml_text_content(basic_status_str);
|
||||
if (timestamp_str != NULL) linphone_free_xml_text_content(timestamp_str);
|
||||
if (contact_str != NULL) linphone_free_xml_text_content(contact_str);
|
||||
if (service_id_str != NULL) linphone_free_xml_text_content(service_id_str);
|
||||
linphone_free_xml_text_content(basic_status_str);
|
||||
}
|
||||
}
|
||||
if (service_object != NULL) xmlXPathFreeObject(service_object);
|
||||
|
|
@ -1796,6 +1792,8 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen
|
|||
return;
|
||||
}
|
||||
|
||||
xmlTextWriterSetIndent(writer,1);
|
||||
|
||||
err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"presence", (const xmlChar *)"urn:ietf:params:xml:ns:pidf");
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ extern "C" {
|
|||
#define ngettext(singular, plural, number) (((number)==1)?(singular):(plural))
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
struct _LinphoneCallParams{
|
||||
belle_sip_object_t base;
|
||||
|
|
@ -105,6 +108,9 @@ struct _LinphoneCallParams{
|
|||
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;
|
||||
LinphoneMediaDirection audio_dir;
|
||||
LinphoneMediaDirection video_dir;
|
||||
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneCallParams);
|
||||
|
|
@ -146,6 +152,17 @@ typedef struct _CallCallbackObj
|
|||
void * _user_data;
|
||||
}CallCallbackObj;
|
||||
|
||||
struct _LinphoneChatMessageCbs {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
LinphoneChatMessageCbsMsgStateChangedCb msg_state_changed;
|
||||
LinphoneChatMessageCbsFileTransferRecvCb file_transfer_recv; /**< Callback to store file received attached to a #LinphoneChatMessage */
|
||||
LinphoneChatMessageCbsFileTransferSendCb file_transfer_send; /**< Callback to collect file chunk to be sent for a #LinphoneChatMessage */
|
||||
LinphoneChatMessageCbsFileTransferProgressIndicationCb file_transfer_progress_indication; /**< Callback to indicate file transfer progress */
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneChatMessageCbs);
|
||||
|
||||
typedef enum _LinphoneChatMessageDir{
|
||||
LinphoneChatMessageIncoming,
|
||||
LinphoneChatMessageOutgoing
|
||||
|
|
@ -154,6 +171,7 @@ typedef enum _LinphoneChatMessageDir{
|
|||
struct _LinphoneChatMessage {
|
||||
belle_sip_object_t base;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneChatMessageCbs *callbacks;
|
||||
LinphoneChatMessageDir dir;
|
||||
char* message;
|
||||
LinphoneChatMessageStateChangedCb cb;
|
||||
|
|
@ -184,6 +202,9 @@ typedef struct StunCandidate{
|
|||
|
||||
|
||||
typedef struct _PortConfig{
|
||||
char multicast_ip[LINPHONE_IPADDR_SIZE];
|
||||
int mcast_rtp_port;
|
||||
int mcast_rtcp_port;
|
||||
int rtp_port;
|
||||
int rtcp_port;
|
||||
}PortConfig;
|
||||
|
|
@ -201,6 +222,7 @@ struct _LinphoneCall{
|
|||
struct _RtpProfile *audio_profile;
|
||||
struct _RtpProfile *video_profile;
|
||||
struct _LinphoneCallLog *log;
|
||||
LinphoneAddress *me; /*Either from or to based on call dir*/
|
||||
SalOp *op;
|
||||
SalOp *ping_op;
|
||||
char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */
|
||||
|
|
@ -213,7 +235,7 @@ struct _LinphoneCall{
|
|||
StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/
|
||||
struct _AudioStream *audiostream; /**/
|
||||
struct _VideoStream *videostream;
|
||||
|
||||
unsigned long video_window_id;
|
||||
MSAudioEndpoint *endpoint; /*used for conferencing*/
|
||||
char *refer_to;
|
||||
LinphoneCallParams *params;
|
||||
|
|
@ -237,10 +259,12 @@ struct _LinphoneCall{
|
|||
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
|
||||
int localdesc_changed;/*not a boolean, contains a mask representing changes*/
|
||||
LinphonePlayer *player;
|
||||
unsigned long bg_task_id; /*used to prevent device to suspend app while a call is received in background*/
|
||||
|
||||
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*/
|
||||
|
||||
char *dtls_certificate_fingerprint; /**> This fingerprint is computed during stream init and is stored in call to be used when making local media description */
|
||||
bool_t refer_pending;
|
||||
bool_t expect_media_in_ack;
|
||||
bool_t audio_muted;
|
||||
|
|
@ -277,6 +301,8 @@ LinphonePlayer *linphone_call_build_player(LinphoneCall*call);
|
|||
|
||||
LinphoneCallParams * linphone_call_params_new(void);
|
||||
SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params);
|
||||
SalStreamDir get_audio_dir_from_call_params(const LinphoneCallParams *params);
|
||||
SalStreamDir get_video_dir_from_call_params(const LinphoneCallParams *params);
|
||||
|
||||
void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos);
|
||||
|
||||
|
|
@ -284,20 +310,6 @@ void linphone_core_update_proxy_register(LinphoneCore *lc);
|
|||
void linphone_core_refresh_subscribes(LinphoneCore *lc);
|
||||
int linphone_core_abort_call(LinphoneCore *lc, LinphoneCall *call, const char *error);
|
||||
const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc);
|
||||
/**
|
||||
* @brief Equivalent to _linphone_core_get_firewall_policy_with_lie(lc, TRUE)
|
||||
* @param lc LinphoneCore instance
|
||||
* @return Fairewall policy
|
||||
*/
|
||||
LinphoneFirewallPolicy _linphone_core_get_firewall_policy(const LinphoneCore *lc);
|
||||
/**
|
||||
* @brief Get the firwall policy which has been set.
|
||||
* @param lc Instance of LinphoneCore
|
||||
* @param lie If true, the configured firewall policy will be returned only if no tunnel are enabled.
|
||||
* Otherwise, NoFirewallPolicy value will be returned.
|
||||
* @return The firewall policy
|
||||
*/
|
||||
LinphoneFirewallPolicy _linphone_core_get_firewall_policy_with_lie(const LinphoneCore *lc, bool_t lie);
|
||||
|
||||
int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphonePresenceModel *presence);
|
||||
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState rstate, const char *message);
|
||||
|
|
@ -353,6 +365,7 @@ static MS2_INLINE void set_string(char **dest, const char *src){
|
|||
|
||||
#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0
|
||||
#define PAYLOAD_TYPE_BITRATE_OVERRIDE PAYLOAD_TYPE_USER_FLAG_3
|
||||
#define PAYLOAD_TYPE_FROZEN_NUMBER PAYLOAD_TYPE_USER_FLAG_4
|
||||
|
||||
void linphone_process_authentication(LinphoneCore* lc, SalOp *op);
|
||||
void linphone_authentication_ok(LinphoneCore *lc, SalOp *op);
|
||||
|
|
@ -362,6 +375,8 @@ void linphone_notify_parse_presence(SalOp *op, const char *content_type, const c
|
|||
void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presence, const char *contact, char **content);
|
||||
void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model);
|
||||
void linphone_proxy_config_process_authentication_failure(LinphoneCore *lc, SalOp *op);
|
||||
void linphone_core_soundcard_hint_check(LinphoneCore* lc);
|
||||
|
||||
|
||||
void linphone_subscription_answered(LinphoneCore *lc, SalOp *op);
|
||||
void linphone_subscription_closed(LinphoneCore *lc, SalOp *op);
|
||||
|
|
@ -395,7 +410,7 @@ void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char
|
|||
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore *lc, int index);
|
||||
void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index);
|
||||
|
||||
int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len);
|
||||
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len);
|
||||
|
||||
void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *msg);
|
||||
void linphone_core_is_composing_received(LinphoneCore *lc, SalOp *op, const SalIsComposing *is_composing);
|
||||
|
|
@ -433,14 +448,21 @@ bool_t linphone_core_symmetric_rtp_enabled(LinphoneCore*lc);
|
|||
|
||||
void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description);
|
||||
|
||||
LINPHONE_PUBLIC bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b);
|
||||
LINPHONE_PUBLIC bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj);
|
||||
typedef enum _LinphoneProxyConfigAddressComparisonResult{
|
||||
LinphoneProxyConfigAddressDifferent,
|
||||
LinphoneProxyConfigAddressEqual,
|
||||
LinphoneProxyConfigAddressWeakEqual
|
||||
} LinphoneProxyConfigAddressComparisonResult;
|
||||
|
||||
LINPHONE_PUBLIC LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b);
|
||||
LINPHONE_PUBLIC LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj);
|
||||
void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj);
|
||||
void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
|
||||
|
||||
/*chat*/
|
||||
void linphone_chat_room_release(LinphoneChatRoom *cr);
|
||||
void linphone_chat_message_destroy(LinphoneChatMessage* msg);
|
||||
void linphone_chat_message_update_state(LinphoneChatMessage* chat_msg );
|
||||
/**/
|
||||
|
||||
struct _LinphoneProxyConfig
|
||||
|
|
@ -459,6 +481,7 @@ struct _LinphoneProxyConfig
|
|||
int expires;
|
||||
int publish_expires;
|
||||
SalOp *op;
|
||||
SalCustomHeader *sent_headers;
|
||||
char *type;
|
||||
struct _SipSetupContext *ssctx;
|
||||
int auth_failures;
|
||||
|
|
@ -579,6 +602,12 @@ typedef struct rtp_config
|
|||
bool_t audio_adaptive_jitt_comp_enabled;
|
||||
bool_t video_adaptive_jitt_comp_enabled;
|
||||
bool_t pad;
|
||||
char* audio_multicast_addr;
|
||||
bool_t audio_multicast_enabled;
|
||||
int audio_multicast_ttl;
|
||||
char* video_multicast_addr;
|
||||
int video_multicast_ttl;
|
||||
bool_t video_multicast_enabled;
|
||||
}rtp_config_t;
|
||||
|
||||
|
||||
|
|
@ -593,6 +622,7 @@ typedef struct net_config
|
|||
int download_bw;
|
||||
int upload_bw;
|
||||
int mtu;
|
||||
OrtpNetworkSimulatorParams netsim_params;
|
||||
bool_t nat_sdp_only;
|
||||
}net_config_t;
|
||||
|
||||
|
|
@ -622,7 +652,9 @@ typedef struct sound_config
|
|||
typedef struct codecs_config
|
||||
{
|
||||
MSList *audio_codecs; /* list of audio codecs in order of preference*/
|
||||
MSList *video_codecs; /* for later use*/
|
||||
MSList *video_codecs;
|
||||
int dyn_pt;
|
||||
int telephone_event_pt;
|
||||
}codecs_config_t;
|
||||
|
||||
typedef struct video_config{
|
||||
|
|
@ -689,7 +721,8 @@ struct _LinphoneCore
|
|||
Sal *sal;
|
||||
LinphoneGlobalState state;
|
||||
struct _LpConfig *config;
|
||||
RtpProfile *default_profile;
|
||||
MSList *default_audio_codecs;
|
||||
MSList *default_video_codecs;
|
||||
net_config_t net_conf;
|
||||
sip_config_t sip_conf;
|
||||
rtp_config_t rtp_conf;
|
||||
|
|
@ -698,8 +731,6 @@ struct _LinphoneCore
|
|||
codecs_config_t codecs_conf;
|
||||
ui_config_t ui_conf;
|
||||
autoreplier_config_t autoreplier_conf;
|
||||
MSList *payload_types;
|
||||
int dyn_pt;
|
||||
LinphoneProxyConfig *default_proxy;
|
||||
MSList *friends;
|
||||
MSList *auth_info;
|
||||
|
|
@ -734,6 +765,7 @@ struct _LinphoneCore
|
|||
MSList *hooks;
|
||||
LinphoneConference conf_ctx;
|
||||
char* zrtp_secrets_cache;
|
||||
char* user_certificates_path;
|
||||
LinphoneVideoPolicy video_policy;
|
||||
bool_t use_files;
|
||||
bool_t apply_nat_settings;
|
||||
|
|
@ -773,6 +805,17 @@ struct _LinphoneCore
|
|||
char *file_transfer_server;
|
||||
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
|
||||
#ifdef ANDROID
|
||||
jobject wifi_lock;
|
||||
jclass wifi_lock_class;
|
||||
jmethodID wifi_lock_acquire_id;
|
||||
jmethodID wifi_lock_release_id;
|
||||
jobject multicast_lock;
|
||||
jclass multicast_lock_class;
|
||||
jmethodID multicast_lock_acquire_id;
|
||||
jmethodID multicast_lock_release_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -889,10 +932,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);
|
||||
|
|
@ -904,9 +946,29 @@ 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);
|
||||
|
||||
struct _LinphoneBuffer {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
uint8_t *content; /**< A pointer to the buffer content */
|
||||
size_t size; /**< The size of the buffer content */
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneBuffer);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* REMOTE PROVISIONING FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
|
@ -975,19 +1037,34 @@ static MS2_INLINE const LinphoneErrorInfo *linphone_error_info_from_sal_op(const
|
|||
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
|
||||
}
|
||||
|
||||
static MS2_INLINE void payload_type_set_enable(PayloadType *pt,int value)
|
||||
{
|
||||
if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \
|
||||
else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED);
|
||||
}
|
||||
|
||||
static MS2_INLINE bool_t payload_type_enabled(const PayloadType *pt) {
|
||||
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
|
||||
}
|
||||
|
||||
bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore);
|
||||
|
||||
const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc);
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
*/
|
||||
|
||||
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
|
||||
BELLE_SIP_TYPE_ID(LinphoneBuffer),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
|
||||
BELLE_SIP_TYPE_ID(LinphoneCall),
|
||||
BELLE_SIP_TYPE_ID(LinphoneCallLog),
|
||||
BELLE_SIP_TYPE_ID(LinphoneCallParams),
|
||||
BELLE_SIP_TYPE_ID(LinphoneChatMessage),
|
||||
BELLE_SIP_TYPE_ID(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)
|
||||
|
|
@ -1035,6 +1112,47 @@ void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore
|
|||
void set_mic_gain_db(AudioStream *st, float gain);
|
||||
void set_playback_gain_db(AudioStream *st, float gain);
|
||||
|
||||
LinphoneMediaDirection media_direction_from_sal_stream_dir(SalStreamDir dir);
|
||||
SalStreamDir sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir);
|
||||
|
||||
/*****************************************************************************
|
||||
* LINPHONE CONTENT PRIVATE ACCESSORS *
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Get the key associated with a RCS file transfer message if encrypted
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The key to encrypt/decrypt the file associated to this content.
|
||||
*/
|
||||
const char *linphone_content_get_key(const LinphoneContent *content);
|
||||
|
||||
/**
|
||||
* Get the size of key associated with a RCS file transfer message if encrypted
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The key size in bytes
|
||||
*/
|
||||
size_t linphone_content_get_key_size(const LinphoneContent *content);
|
||||
/**
|
||||
* Set the key associated with a RCS file transfer message if encrypted
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @param[in] key The key to be used to encrypt/decrypt file associated to this content.
|
||||
*/
|
||||
void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength);
|
||||
|
||||
/**
|
||||
* Get the address of the crypto context associated with a RCS file transfer message if encrypted
|
||||
* @param[in] content LinphoneContent object.
|
||||
* @return The address of the pointer to the crypto context. Crypto context is managed(alloc/free)
|
||||
* by the encryption/decryption functions, so we give the address to store/retrieve the pointer
|
||||
*/
|
||||
void ** linphone_content_get_cryptoContext_address(LinphoneContent *content);
|
||||
|
||||
#ifdef ANDROID
|
||||
void linphone_core_wifi_lock_acquire(LinphoneCore *lc);
|
||||
void linphone_core_wifi_lock_release(LinphoneCore *lc);
|
||||
void linphone_core_multicast_lock_acquire(LinphoneCore *lc);
|
||||
void linphone_core_multicast_lock_release(LinphoneCore *lc);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,33 +41,41 @@ static void linphone_proxy_config_store_server_config(LinphoneProxyConfig* obj)
|
|||
obj->saved_proxy = NULL;
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b) {
|
||||
LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b) {
|
||||
if (a == NULL && b == NULL)
|
||||
return TRUE;
|
||||
return LinphoneProxyConfigAddressEqual;
|
||||
else if (!a || !b)
|
||||
return FALSE;
|
||||
return LinphoneProxyConfigAddressDifferent;
|
||||
|
||||
if (linphone_address_equal(a,b))
|
||||
return LinphoneProxyConfigAddressEqual;
|
||||
if (linphone_address_weak_equal(a,b)) {
|
||||
/*also check both transport and uri */
|
||||
return linphone_address_is_secure(a) == linphone_address_is_secure(b) && linphone_address_get_transport(a) == linphone_address_get_transport(b);
|
||||
} else
|
||||
return FALSE; /*either username, domain or port ar not equals*/
|
||||
|
||||
if (linphone_address_is_secure(a) == linphone_address_is_secure(b) && linphone_address_get_transport(a) == linphone_address_get_transport(b))
|
||||
return LinphoneProxyConfigAddressWeakEqual;
|
||||
else
|
||||
return LinphoneProxyConfigAddressDifferent;
|
||||
}
|
||||
return LinphoneProxyConfigAddressDifferent; /*either username, domain or port ar not equals*/
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj) {
|
||||
LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj) {
|
||||
LinphoneAddress *current_identity=obj->reg_identity?linphone_address_new(obj->reg_identity):NULL;
|
||||
LinphoneAddress *current_proxy=obj->reg_proxy?linphone_address_new(obj->reg_proxy):NULL;
|
||||
bool_t result=FALSE;
|
||||
LinphoneProxyConfigAddressComparisonResult result_identity;
|
||||
LinphoneProxyConfigAddressComparisonResult result;
|
||||
|
||||
if (!linphone_proxy_config_address_equal(obj->saved_identity,current_identity)){
|
||||
result=TRUE;
|
||||
goto end;
|
||||
}
|
||||
if (!linphone_proxy_config_address_equal(obj->saved_proxy,current_proxy)){
|
||||
result=TRUE;
|
||||
goto end;
|
||||
}
|
||||
result = linphone_proxy_config_address_equal(obj->saved_identity,current_identity);
|
||||
if (result == LinphoneProxyConfigAddressDifferent) goto end;
|
||||
result_identity = result;
|
||||
|
||||
result = linphone_proxy_config_address_equal(obj->saved_proxy,current_proxy);
|
||||
if (result == LinphoneProxyConfigAddressDifferent) goto end;
|
||||
/** If the proxies are equal use the result of the difference between the identities,
|
||||
* otherwise the result is weak-equal and so weak-equal must be returned even if the
|
||||
* identities were equal.
|
||||
*/
|
||||
if (result == LinphoneProxyConfigAddressEqual) result = result_identity;
|
||||
|
||||
end:
|
||||
if (current_identity) linphone_address_destroy(current_identity);
|
||||
|
|
@ -174,6 +182,7 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
|
|||
if (obj->contact_uri_params) ms_free(obj->contact_uri_params);
|
||||
if (obj->saved_proxy!=NULL) linphone_address_destroy(obj->saved_proxy);
|
||||
if (obj->saved_identity!=NULL) linphone_address_destroy(obj->saved_identity);
|
||||
if (obj->sent_headers!=NULL) sal_custom_header_free(obj->sent_headers);
|
||||
_linphone_proxy_config_release_ops(obj);
|
||||
}
|
||||
|
||||
|
|
@ -459,7 +468,7 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
|
|||
sal_op_release(obj->op);
|
||||
obj->op=sal_op_new(obj->lc->sal);
|
||||
|
||||
linphone_configure_op(obj->lc, obj->op, to, NULL, FALSE);
|
||||
linphone_configure_op(obj->lc, obj->op, to, obj->sent_headers, FALSE);
|
||||
linphone_address_destroy(to);
|
||||
|
||||
if ((contact=guess_contact_for_register(obj))) {
|
||||
|
|
@ -871,7 +880,7 @@ static void lookup_dial_plan(const char *ccc, dial_plan_t *plan){
|
|||
strcpy(plan->ccc,ccc);
|
||||
}
|
||||
|
||||
static bool_t is_a_phone_number(const char *username){
|
||||
bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig *proxy, const char *username){
|
||||
const char *p;
|
||||
for(p=username;*p!='\0';++p){
|
||||
if (isdigit(*p) ||
|
||||
|
|
@ -919,9 +928,8 @@ static void replace_plus(const char *src, char *dest, size_t destlen, const char
|
|||
}
|
||||
|
||||
|
||||
int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len){
|
||||
int numlen;
|
||||
if (is_a_phone_number(username)){
|
||||
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len){
|
||||
if (linphone_proxy_config_is_phone_number(proxy, username)){
|
||||
char *flatten;
|
||||
flatten=flatten_number(username);
|
||||
ms_debug("Flattened number is '%s'",flatten);
|
||||
|
|
@ -930,7 +938,6 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
/*no prefix configured, nothing else to do*/
|
||||
strncpy(result,flatten,result_len);
|
||||
ms_free(flatten);
|
||||
return 0;
|
||||
}else{
|
||||
dial_plan_t dialplan;
|
||||
lookup_dial_plan(proxy->dial_prefix,&dialplan);
|
||||
|
|
@ -941,8 +948,8 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
/*eventually replace the plus*/
|
||||
replace_plus(flatten,result,result_len,proxy->dial_escape_plus ? dialplan.icp : NULL);
|
||||
ms_free(flatten);
|
||||
return 0;
|
||||
}else{
|
||||
int numlen;
|
||||
int i=0;
|
||||
int skip;
|
||||
numlen=strlen(flatten);
|
||||
|
|
@ -967,8 +974,11 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
ms_free(flatten);
|
||||
}
|
||||
}
|
||||
}else strncpy(result,username,result_len);
|
||||
return 0;
|
||||
return TRUE;
|
||||
} else {
|
||||
strncpy(result,username,result_len);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -976,14 +986,19 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
**/
|
||||
int linphone_proxy_config_done(LinphoneProxyConfig *obj)
|
||||
{
|
||||
LinphoneProxyConfigAddressComparisonResult res;
|
||||
|
||||
if (!linphone_proxy_config_check(obj->lc,obj))
|
||||
return -1;
|
||||
|
||||
/*check if server address as changed*/
|
||||
if (linphone_proxy_config_is_server_config_changed(obj)) {
|
||||
res = linphone_proxy_config_is_server_config_changed(obj);
|
||||
if (res != LinphoneProxyConfigAddressEqual) {
|
||||
/* server config has changed, need to unregister from previous first*/
|
||||
if (obj->op) {
|
||||
_linphone_proxy_config_unregister(obj);
|
||||
if (res == LinphoneProxyConfigAddressDifferent) {
|
||||
_linphone_proxy_config_unregister(obj);
|
||||
}
|
||||
sal_op_set_user_pointer(obj->op,NULL); /*we don't want to receive status for this un register*/
|
||||
sal_op_unref(obj->op); /*but we keep refresher to handle authentication if needed*/
|
||||
obj->op=NULL;
|
||||
|
|
@ -1133,6 +1148,17 @@ struct _LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig
|
|||
return obj->lc;
|
||||
}
|
||||
|
||||
const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, const char *header_name){
|
||||
const SalCustomHeader *ch;
|
||||
if (!cfg->op) return NULL;
|
||||
ch = sal_op_get_recv_custom_header(cfg->op);
|
||||
return sal_custom_header_find(ch, header_name);
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_custom_header(LinphoneProxyConfig *cfg, const char *header_name, const char *header_value){
|
||||
cfg->sent_headers=sal_custom_header_append(cfg->sent_headers, header_name, header_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a proxy configuration.
|
||||
* This will start registration on the proxy, if registration is enabled.
|
||||
|
|
|
|||
|
|
@ -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,17 @@ 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));
|
||||
ms_free(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 +354,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",
|
||||
|
|
|
|||
|
|
@ -60,33 +60,38 @@ static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml
|
|||
, error_msg);
|
||||
}
|
||||
|
||||
static char *load_file_content(const char *path){
|
||||
FILE *f=fopen(path,"rb");
|
||||
size_t bufsize=2048;
|
||||
size_t step=bufsize;
|
||||
size_t pos=0;
|
||||
size_t count;
|
||||
char *buffer=ms_malloc(bufsize+1);
|
||||
if (!f) {
|
||||
ms_error("load_file_content(): could not open [%s]",path);
|
||||
return NULL;
|
||||
}
|
||||
while((count=fread(buffer+pos, 1, step, f))>0){
|
||||
pos+=count;
|
||||
if (pos+step>=bufsize){
|
||||
bufsize*=2;
|
||||
buffer=ms_realloc(buffer, bufsize+1);
|
||||
}
|
||||
}
|
||||
buffer[pos]='\0';
|
||||
fclose(f);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path){
|
||||
int status = -1;
|
||||
FILE* f = fopen(file_path, "r");
|
||||
char* provisioning=load_file_content(file_path);
|
||||
|
||||
if( f ){
|
||||
long fsize;
|
||||
char* provisioning;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
provisioning = ms_malloc(fsize + 1);
|
||||
provisioning[fsize]='\0';
|
||||
if (fread(provisioning, fsize, 1, f)==0){
|
||||
ms_error("Could not read xml provisioning file from %s",file_path);
|
||||
status=-1;
|
||||
}else{
|
||||
linphone_remote_provisioning_apply(lc, provisioning);
|
||||
status = 0;
|
||||
}
|
||||
if (provisioning){
|
||||
linphone_remote_provisioning_apply(lc, provisioning);
|
||||
status = 0;
|
||||
ms_free(provisioning);
|
||||
fclose(f);
|
||||
} else {
|
||||
ms_error("Couldn't open file %s for provisioning", file_path);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,9 +62,10 @@ SalMediaDescription *sal_media_description_new(){
|
|||
static void sal_media_description_destroy(SalMediaDescription *md){
|
||||
int i;
|
||||
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
|
||||
ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
|
||||
ms_list_free(md->streams[i].payloads);
|
||||
ms_list_free_with_data(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
|
||||
ms_list_free_with_data(md->streams[i].already_assigned_payloads,(void (*)(void *))payload_type_destroy);
|
||||
md->streams[i].payloads=NULL;
|
||||
md->streams[i].already_assigned_payloads=NULL;
|
||||
}
|
||||
ms_free(md);
|
||||
}
|
||||
|
|
@ -120,7 +121,9 @@ SalStreamDescription * sal_media_description_find_secure_stream_of_type(SalMedia
|
|||
}
|
||||
|
||||
SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescription *md, SalStreamType type) {
|
||||
SalStreamDescription *desc = sal_media_description_find_stream(md, SalProtoRtpSavpf, type);
|
||||
SalStreamDescription *desc = sal_media_description_find_stream(md, SalProtoUdpTlsRtpSavpf, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoUdpTlsRtpSavp, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpSavpf, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpSavp, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpAvpf, type);
|
||||
if (desc == NULL) desc = sal_media_description_find_stream(md, SalProtoRtpAvp, type);
|
||||
|
|
@ -194,13 +197,17 @@ bool_t sal_stream_description_active(const SalStreamDescription *sd) {
|
|||
}
|
||||
|
||||
bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd) {
|
||||
return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf));
|
||||
return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf) || (sd->proto == SalProtoUdpTlsRtpSavpf));
|
||||
}
|
||||
|
||||
bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd) {
|
||||
return ((sd->proto == SalProtoRtpSavp) || (sd->proto == SalProtoRtpSavpf));
|
||||
}
|
||||
|
||||
bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd) {
|
||||
return ((sd->proto == SalProtoUdpTlsRtpSavp) || (sd->proto == SalProtoUdpTlsRtpSavpf));
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_avpf(const SalMediaDescription *md) {
|
||||
int i;
|
||||
if (md->nb_streams == 0) return FALSE;
|
||||
|
|
@ -221,6 +228,16 @@ bool_t sal_media_description_has_srtp(const SalMediaDescription *md) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_dtls(const SalMediaDescription *md) {
|
||||
int i;
|
||||
if (md->nb_streams == 0) return FALSE;
|
||||
for (i = 0; i < md->nb_streams; i++) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (sal_stream_description_has_dtls(&md->streams[i]) != TRUE) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
static bool_t fmtp_equals(const char *p1, const char *p2){
|
||||
if (p1 && p2 && strcmp(p1,p2)==0) return TRUE;
|
||||
|
|
@ -301,6 +318,10 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre
|
|||
if (sd1->ptime != sd2->ptime) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
|
||||
if (sd1->dir != sd2->dir) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
|
||||
|
||||
/*DTLS*/
|
||||
if (sd1->dtls_role != sd2->dtls_role) result |= SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED;
|
||||
if (strcmp(sd1->dtls_fingerprint, sd2->dtls_fingerprint) != 0) result |= SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -607,8 +628,10 @@ const char* sal_media_proto_to_string(SalMediaProto type) {
|
|||
switch (type) {
|
||||
case SalProtoRtpAvp:return "RTP/AVP";
|
||||
case SalProtoRtpSavp:return "RTP/SAVP";
|
||||
case SalProtoUdpTlsRtpSavp:return "UDP/TLS/RTP/SAVP";
|
||||
case SalProtoRtpAvpf:return "RTP/AVPF";
|
||||
case SalProtoRtpSavpf:return "RTP/SAVPF";
|
||||
case SalProtoUdpTlsRtpSavpf:return "UDP/TLS/RTP/SAVPF";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:");
|
||||
|
|
|
|||
98
gtk/CMakeLists.txt
Normal file
98
gtk/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
############################################################################
|
||||
# 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
|
||||
)
|
||||
|
||||
if(ENABLE_ASSISTANT)
|
||||
list(APPEND SOURCE_FILES setupwizard.c)
|
||||
endif()
|
||||
|
||||
if(GETTEXT_FOUND)
|
||||
add_definitions("-DENABLE_NLS")
|
||||
endif()
|
||||
|
||||
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()
|
||||
if(ENABLE_ASSISTANT)
|
||||
target_link_libraries(linphone-gtk ${SOUP_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>
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus st
|
|||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_YES_NO,
|
||||
"%s","Did you hear three beeps ?");
|
||||
"%s",_("Did you hear three beeps ?"));
|
||||
|
||||
g_signal_connect(G_OBJECT (dialog), "response",
|
||||
G_CALLBACK (dialog_click),speaker_page);
|
||||
|
|
@ -289,12 +289,12 @@ static void open_mixer(){
|
|||
|
||||
#ifdef WIN32
|
||||
if(!g_spawn_command_line_async("control mmsys.cpl",&error)){
|
||||
display_popup(GTK_MESSAGE_WARNING,"Sound preferences not found ");
|
||||
display_popup(GTK_MESSAGE_WARNING,_("Sound preferences not found "));
|
||||
g_error_free(error);
|
||||
}
|
||||
#elif __APPLE__
|
||||
if(!g_spawn_command_line_async("open /System/Library/PreferencePanes/Sound.prefPane",&error)){
|
||||
display_popup(GTK_MESSAGE_WARNING,"Sound preferences not found ");
|
||||
display_popup(GTK_MESSAGE_WARNING,_("Sound preferences not found "));
|
||||
g_error_free(error);
|
||||
}
|
||||
#else
|
||||
|
|
@ -303,7 +303,7 @@ static void open_mixer(){
|
|||
if(!g_spawn_command_line_async("kmix",&error)){
|
||||
if(!g_spawn_command_line_async("mate-volume-control",&error)){
|
||||
if(!g_spawn_command_line_async("xterm alsamixer",&error)){
|
||||
display_popup(GTK_MESSAGE_WARNING,"Cannot launch system sound control ");
|
||||
display_popup(GTK_MESSAGE_WARNING,_("Cannot launch system sound control "));
|
||||
g_error_free(error);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -331,7 +331,7 @@ static GtkWidget *create_mic_page(){
|
|||
GtkWidget *capture_device=gtk_combo_box_new();
|
||||
GtkWidget *box = gtk_vbox_new(FALSE,0);
|
||||
GtkWidget *label_audiolevel=gtk_label_new(_("No voice"));
|
||||
GtkWidget *mixer_button=gtk_button_new_with_label("System sound preferences");
|
||||
GtkWidget *mixer_button=gtk_button_new_with_label(_("System sound preferences"));
|
||||
GtkWidget *image;
|
||||
|
||||
image=gtk_image_new_from_stock(GTK_STOCK_PREFERENCES,GTK_ICON_SIZE_MENU);
|
||||
|
|
@ -370,7 +370,7 @@ static GtkWidget *create_speaker_page(){
|
|||
GtkWidget *labelSpeakerLevel=gtk_label_new(_("Play three beeps"));
|
||||
GtkWidget *spk_button=gtk_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
|
||||
GtkWidget *playback_device=gtk_combo_box_new();
|
||||
GtkWidget *mixer_button=gtk_button_new_with_label("System sound preferences");
|
||||
GtkWidget *mixer_button=gtk_button_new_with_label(_("System sound preferences"));
|
||||
GtkWidget *image;
|
||||
const char **sound_devices;
|
||||
|
||||
|
|
@ -402,8 +402,8 @@ static GtkWidget *create_play_record_page(){
|
|||
GtkWidget *vbox=gtk_table_new(2,2,FALSE);
|
||||
GtkWidget *labelRecord=gtk_label_new(_("Press the record button and say some words"));
|
||||
GtkWidget *labelPlay=gtk_label_new(_("Listen to your record voice"));
|
||||
GtkWidget *rec_button=gtk_toggle_button_new_with_label("Record");
|
||||
GtkWidget *play_button=gtk_toggle_button_new_with_label("Play");
|
||||
GtkWidget *rec_button=gtk_toggle_button_new_with_label(_("Record"));
|
||||
GtkWidget *play_button=gtk_toggle_button_new_with_label(_("Play"));
|
||||
GtkWidget *image;
|
||||
|
||||
image=gtk_image_new_from_stock(GTK_STOCK_MEDIA_RECORD,GTK_ICON_SIZE_MENU);
|
||||
|
|
@ -466,10 +466,17 @@ static void prepare(GtkAssistant *w){
|
|||
}
|
||||
|
||||
void linphone_gtk_close_audio_assistant(GtkWidget *w){
|
||||
gchar *path = g_object_get_data(G_OBJECT(audio_assistant),"path");
|
||||
gchar *path;
|
||||
AudioStream *stream;
|
||||
|
||||
path = g_object_get_data(G_OBJECT(audio_assistant),"path");
|
||||
if(path != NULL){
|
||||
g_unlink(path);
|
||||
}
|
||||
stream = (AudioStream *)g_object_get_data(G_OBJECT(audio_assistant), "stream");
|
||||
if(stream) {
|
||||
audio_stream_stop(stream);
|
||||
}
|
||||
gtk_widget_destroy(w);
|
||||
if(linphone_gtk_get_audio_assistant_option()){
|
||||
gtk_main_quit();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
37
gtk/chat.c
37
gtk/chat.c
|
|
@ -161,16 +161,19 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
|
|||
if(g_strcmp0(from_message,from_str)!=0){
|
||||
gtk_text_buffer_get_iter_at_offset(buffer,&iter,off);
|
||||
gtk_text_buffer_get_end_iter(buffer,&iter);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,get_display_name(from),-1,"bold",me ? "bg":NULL,NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, get_display_name(from), -1,
|
||||
"bold", me ? "bg" : NULL, me ? "font_black" : NULL, NULL);
|
||||
gtk_text_buffer_get_end_iter(buffer,&iter);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter," : ",-1,"bold",me ? "bg":NULL,NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter, " : ", -1,
|
||||
"bold", me ? "bg" : NULL, me ? "font_black" : NULL, NULL);
|
||||
gtk_text_buffer_get_end_iter(buffer,&iter);
|
||||
gtk_text_buffer_insert(buffer,&iter,"\n",-1);
|
||||
g_free(from_message);
|
||||
g_object_set_data(G_OBJECT(w),"from_message",g_strdup(from_str));
|
||||
}
|
||||
gtk_text_buffer_get_end_iter(buffer,&iter);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,linphone_chat_message_get_text(msg),-1,"margin",me ? "bg":NULL,NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, linphone_chat_message_get_text(msg), -1,
|
||||
"margin", me ? "bg" : NULL, me ? "font_black" : NULL, NULL);
|
||||
gtk_text_buffer_get_end_iter(buffer,&iter);
|
||||
gtk_text_buffer_insert(buffer,&iter,"\n",-1);
|
||||
gtk_text_buffer_get_end_iter(buffer,&iter);
|
||||
|
|
@ -276,7 +279,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 +303,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);
|
||||
|
||||
|
|
@ -375,8 +381,9 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
|
|||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
|
||||
GtkWidget *text=linphone_gtk_get_widget(chat_view,"textview");
|
||||
GdkColor color;
|
||||
GdkColor colorb;
|
||||
GdkColor color_grey = {0, 32512, 32512, 32512};
|
||||
GdkColor color_light_grey = {0, 56832, 60928, 61952};
|
||||
GdkColor color_black = {0};
|
||||
int idx;
|
||||
GtkWidget *button;
|
||||
GtkWidget *entry = linphone_gtk_get_widget(chat_view,"text_entry");
|
||||
|
|
@ -384,13 +391,6 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
|
|||
GHashTable *table;
|
||||
char *with_str;
|
||||
|
||||
color.red = 32512;
|
||||
color.green = 32512;
|
||||
color.blue = 32512;
|
||||
colorb.red = 56832;
|
||||
colorb.green = 60928;
|
||||
colorb.blue = 61952;
|
||||
|
||||
with_str=linphone_address_as_string_uri_only(with);
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text),GTK_WRAP_WORD_CHAR);
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(text),FALSE);
|
||||
|
|
@ -414,11 +414,13 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
|
|||
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
|
||||
"small","size",9*PANGO_SCALE,NULL);
|
||||
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
|
||||
"font_grey","foreground-gdk",&color,NULL);
|
||||
"font_grey","foreground-gdk",&color_grey,NULL);
|
||||
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
|
||||
"font_black","foreground-gdk",&color_black,NULL);
|
||||
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
|
||||
"margin","indent",10,NULL);
|
||||
gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)),
|
||||
"bg","paragraph-background-gdk",&colorb,NULL);
|
||||
"bg","paragraph-background-gdk",&color_light_grey,NULL);
|
||||
messages = linphone_chat_room_get_history(cr,NB_MSG_HIST);
|
||||
display_history_message(chat_view,messages,with);
|
||||
button = linphone_gtk_get_widget(chat_view,"send");
|
||||
|
|
@ -471,8 +473,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>
|
||||
|
|
|
|||
|
|
@ -428,7 +428,7 @@ void linphone_gtk_update_video_button(LinphoneCall *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),
|
||||
|
|
@ -680,6 +680,12 @@ void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){
|
|||
gtk_widget_hide(status_icon);
|
||||
gtk_widget_hide(verify_button);
|
||||
break;
|
||||
case LinphoneMediaEncryptionDTLS:
|
||||
gtk_widget_show_all(encryption_box);
|
||||
gtk_label_set_markup(GTK_LABEL(label),_("Secured by DTLS"));
|
||||
gtk_widget_hide(status_icon);
|
||||
gtk_widget_hide(verify_button);
|
||||
break;
|
||||
case LinphoneMediaEncryptionZRTP:
|
||||
{
|
||||
gchar *text=g_strdup_printf(_("Secured by ZRTP - [auth token: %s]"),linphone_call_get_authentication_token(call));
|
||||
|
|
@ -715,7 +721,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"));
|
||||
|
|
@ -768,7 +774,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>
|
||||
|
|
|
|||
|
|
@ -199,4 +199,5 @@ void linphone_gtk_close_config_fetching(GtkWidget *w, LinphoneConfiguringState s
|
|||
const char *linphone_gtk_get_sound_path(const char *file);
|
||||
void linphone_gtk_in_call_show_video(LinphoneCall *call);
|
||||
char *linphone_gtk_address(const LinphoneAddress *addr);/*return human readable identifier for a LinphoneAddress */
|
||||
GtkWidget *linphone_gtk_get_camera_preview_window(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,6 @@ static FILE *linphone_gtk_log_init()
|
|||
|
||||
static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg)
|
||||
{
|
||||
time_t now;
|
||||
FILE *outlog;
|
||||
|
||||
outlog = linphone_gtk_log_init();
|
||||
|
|
@ -176,12 +175,11 @@ static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg)
|
|||
logfile_date_format in the GtkUi section of the config file,
|
||||
but it defaults to something compact, but yet readable. */
|
||||
const char *lname="undef";
|
||||
char date[256];
|
||||
|
||||
/* Convert level constant to text */
|
||||
switch(lev){
|
||||
case ORTP_DEBUG:
|
||||
lname="debug";
|
||||
lname="debug ";
|
||||
break;
|
||||
case ORTP_MESSAGE:
|
||||
lname="message";
|
||||
|
|
@ -190,23 +188,16 @@ static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg)
|
|||
lname="warning";
|
||||
break;
|
||||
case ORTP_ERROR:
|
||||
lname="error";
|
||||
lname="error ";
|
||||
break;
|
||||
case ORTP_FATAL:
|
||||
lname="fatal";
|
||||
lname="fatal ";
|
||||
break;
|
||||
default:
|
||||
lname="undef";
|
||||
lname="undef ";
|
||||
break;
|
||||
}
|
||||
/* Get current time and format it properly */
|
||||
now = time(NULL);
|
||||
strftime(date, sizeof(date), dateformat, localtime(&now));
|
||||
/* Now print out the message to the logfile. We don't flush,
|
||||
maybe we should do to ensure that we have all the messages in
|
||||
case of a crash (which is one of the main reasons we have a
|
||||
log facility in the first place). */
|
||||
fprintf(outlog, "[%s] [%s] %s\n", date, lname, msg);
|
||||
fprintf(outlog, "[%s] %s\n", lname, msg);
|
||||
fflush(outlog);
|
||||
}
|
||||
}
|
||||
|
|
@ -335,13 +326,24 @@ gboolean linphone_gtk_check_logs(){
|
|||
* Called from any linphone thread.
|
||||
*/
|
||||
void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args){
|
||||
gchar *msg=g_strdup_vprintf(fmt,args);
|
||||
LinphoneGtkLog *lgl=g_new(LinphoneGtkLog,1);
|
||||
gchar *msg=g_strdup_vprintf(fmt,args);
|
||||
gchar *dated_msg;
|
||||
struct timeval tp;
|
||||
struct tm *lt;
|
||||
time_t tt;
|
||||
|
||||
ortp_gettimeofday(&tp, NULL);
|
||||
tt = (time_t)tp.tv_sec;
|
||||
lt = localtime((const time_t*)&tt);
|
||||
dated_msg=g_strdup_printf("%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i %s",
|
||||
1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tp.tv_usec / 1000), msg);
|
||||
g_free(msg);
|
||||
lgl->lev=lev;
|
||||
lgl->msg=msg;
|
||||
lgl->msg=dated_msg;
|
||||
linphone_gtk_log_file(lev, dated_msg);
|
||||
g_static_mutex_lock(&log_mutex);
|
||||
log_queue=g_list_append(log_queue,lgl);
|
||||
linphone_gtk_log_file(lev, msg);
|
||||
g_static_mutex_unlock(&log_mutex);
|
||||
}
|
||||
|
||||
|
|
|
|||
57
gtk/main.c
57
gtk/main.c
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "linphone.h"
|
||||
#include "lpconfig.h"
|
||||
#include "liblinphone_gitversion.h"
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
@ -50,6 +51,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
|
||||
|
||||
static LinphoneCore *the_core=NULL;
|
||||
|
|
@ -77,6 +79,7 @@ void linphone_gtk_status_icon_set_blinking(gboolean val);
|
|||
void _linphone_gtk_enable_video(gboolean val);
|
||||
void linphone_gtk_on_uribar_changed(GtkEditable *uribar, gpointer user_data);
|
||||
static void linphone_gtk_init_ui(void);
|
||||
static void linphone_gtk_quit(void);
|
||||
|
||||
#ifndef HAVE_GTK_OSX
|
||||
static gint main_window_x=0;
|
||||
|
|
@ -90,6 +93,7 @@ static int start_option = START_LINPHONE;
|
|||
static gboolean no_video=FALSE;
|
||||
static gboolean iconified=FALSE;
|
||||
static gboolean run_audio_assistant=FALSE;
|
||||
static gboolean selftest=FALSE;
|
||||
static gchar *workingdir=NULL;
|
||||
static char *progpath=NULL;
|
||||
gchar *linphone_logfile=NULL;
|
||||
|
|
@ -162,6 +166,13 @@ static GOptionEntry linphone_options[]={
|
|||
.arg_data = (gpointer) &run_audio_assistant,
|
||||
.description = N_("Run the audio assistant")
|
||||
},
|
||||
{
|
||||
.long_name = "selftest",
|
||||
.short_name = '\0',
|
||||
.arg = G_OPTION_ARG_NONE,
|
||||
.arg_data = (gpointer) &selftest,
|
||||
.description = N_("Run self test and exit 0 if succeed")
|
||||
},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
@ -172,9 +183,11 @@ static GOptionEntry linphone_options[]={
|
|||
#ifndef WIN32
|
||||
#define CONFIG_FILE ".linphonerc"
|
||||
#define SECRETS_FILE ".linphone-zidcache"
|
||||
#define CERTIFICATES_PATH ".linphone-usr-crt"
|
||||
#else
|
||||
#define CONFIG_FILE "linphonerc"
|
||||
#define SECRETS_FILE "linphone-zidcache"
|
||||
#define CERTIFICATES_PATH "linphone-usr-crt"
|
||||
#endif
|
||||
|
||||
char *linphone_gtk_get_config_file(const char *filename){
|
||||
|
|
@ -279,6 +292,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
const char *factory_config_file, const char *db_file) {
|
||||
LinphoneCoreVTable vtable={0};
|
||||
gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE);
|
||||
gchar *user_certificates_dir=linphone_gtk_get_config_file(CERTIFICATES_PATH);
|
||||
|
||||
vtable.global_state_changed=linphone_gtk_global_state_changed;
|
||||
vtable.call_state_changed=linphone_gtk_call_state_changed;
|
||||
|
|
@ -316,6 +330,8 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
|
||||
linphone_core_set_zrtp_secrets_file(the_core,secrets_file);
|
||||
g_free(secrets_file);
|
||||
linphone_core_set_user_certificates_path(the_core,user_certificates_dir);
|
||||
g_free(user_certificates_dir);
|
||||
linphone_core_enable_video_capture(the_core, TRUE);
|
||||
linphone_core_enable_video_display(the_core, TRUE);
|
||||
linphone_core_set_native_video_window_id(the_core,-1);/*don't create the window*/
|
||||
|
|
@ -547,7 +563,7 @@ void linphone_gtk_show_about(){
|
|||
}
|
||||
g_free(license);
|
||||
}
|
||||
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LINPHONE_VERSION);
|
||||
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LIBLINPHONE_GIT_VERSION);
|
||||
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("title","Linphone"));
|
||||
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("home","http://www.linphone.org"));
|
||||
if (logo) gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),logo);
|
||||
|
|
@ -818,9 +834,6 @@ bool_t linphone_gtk_video_enabled(void){
|
|||
|
||||
void linphone_gtk_show_main_window(){
|
||||
GtkWidget *w=linphone_gtk_get_main_window();
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview",
|
||||
VIDEOSELFVIEW_DEFAULT));
|
||||
gtk_widget_show(w);
|
||||
gtk_window_present(GTK_WINDOW(w));
|
||||
}
|
||||
|
|
@ -1014,13 +1027,6 @@ void _linphone_gtk_enable_video(gboolean val){
|
|||
linphone_core_enable_video_capture(linphone_gtk_get_core(), TRUE);
|
||||
linphone_core_enable_video_display(linphone_gtk_get_core(), TRUE);
|
||||
linphone_core_set_video_policy(linphone_gtk_get_core(),&policy);
|
||||
|
||||
if (val){
|
||||
linphone_core_enable_video_preview(linphone_gtk_get_core(),
|
||||
linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT));
|
||||
}else{
|
||||
linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_enable_video(GtkWidget *w){
|
||||
|
|
@ -1032,7 +1038,6 @@ void linphone_gtk_enable_video(GtkWidget *w){
|
|||
void linphone_gtk_enable_self_view(GtkWidget *w){
|
||||
gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w));
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
linphone_core_enable_video_preview(lc,val);
|
||||
linphone_core_enable_self_view(lc,val);
|
||||
linphone_gtk_set_ui_config_int("videoselfview",val);
|
||||
}
|
||||
|
|
@ -1228,14 +1233,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;
|
||||
}
|
||||
|
||||
|
|
@ -1314,6 +1324,9 @@ static void linphone_gtk_global_state_changed(LinphoneCore *lc, LinphoneGlobalSt
|
|||
break;
|
||||
case LinphoneGlobalOn:
|
||||
linphone_gtk_init_ui();
|
||||
if (selftest) {
|
||||
gtk_timeout_add(300,(GtkFunction)gtk_main_quit,NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1821,10 +1834,11 @@ void linphone_gtk_manage_login(void){
|
|||
gboolean linphone_gtk_close(GtkWidget *mw){
|
||||
/*shutdown calls if any*/
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
GtkWidget *camera_preview=linphone_gtk_get_camera_preview_window();
|
||||
if (linphone_core_in_call(lc)){
|
||||
linphone_core_terminate_all_calls(lc);
|
||||
}
|
||||
linphone_core_enable_video_preview(lc,FALSE);
|
||||
if (camera_preview) gtk_widget_destroy(camera_preview);
|
||||
#ifdef __APPLE__ /*until with have a better option*/
|
||||
gtk_window_iconify(GTK_WINDOW(mw));
|
||||
#else
|
||||
|
|
@ -1835,13 +1849,6 @@ gboolean linphone_gtk_close(GtkWidget *mw){
|
|||
|
||||
#ifdef HAVE_GTK_OSX
|
||||
static gboolean on_window_state_event(GtkWidget *w, GdkEventWindowState *event){
|
||||
bool_t video_enabled=linphone_gtk_video_enabled();
|
||||
if ((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ||(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ){
|
||||
linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
|
||||
}else{
|
||||
linphone_core_enable_video_preview(linphone_gtk_get_core(),
|
||||
linphone_gtk_get_ui_config_int("videoselfview",VIDEOSELFVIEW_DEFAULT) && video_enabled);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1952,6 +1959,7 @@ static void linphone_gtk_init_main_window(){
|
|||
g_signal_connect(G_OBJECT(main_window), "window-state-event",G_CALLBACK(on_window_state_event), NULL);
|
||||
#endif
|
||||
linphone_gtk_check_menu_items();
|
||||
linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE);
|
||||
}
|
||||
|
||||
void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
|
||||
|
|
@ -2096,6 +2104,7 @@ int main(int argc, char *argv[]){
|
|||
LpConfig *factory;
|
||||
const char *db_file;
|
||||
GError *error=NULL;
|
||||
const char *tmp;
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
||||
g_thread_init(NULL);
|
||||
|
|
@ -2105,6 +2114,8 @@ int main(int argc, char *argv[]){
|
|||
progpath = strdup(argv[0]);
|
||||
|
||||
config_file=linphone_gtk_get_config_file(NULL);
|
||||
|
||||
workingdir= (tmp=g_getenv("LINPHONE_WORKDIR")) ? g_strdup(tmp) : NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
/*workaround for windows: sometimes LANG is defined to an integer value, not understood by gtk */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue