mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-18 11:38:08 +00:00
Merge branch 'master' of git.linphone.org:linphone
This commit is contained in:
commit
9ca718d11f
58 changed files with 1338 additions and 444 deletions
60
CMakeLists.txt
Normal file
60
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
project(LINPHONE C)
|
||||
|
||||
option(LINPHONE_ENABLE_VIDEO "Build linphone with video support." ON)
|
||||
|
||||
if(NOT ORTP_ROOT_DIR)
|
||||
set(ORTP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/oRTP)
|
||||
endif()
|
||||
if(NOT ORTP_INCLUDE_DIR)
|
||||
set(ORTP_INCLUDE_DIR ${ORTP_ROOT_DIR}/include)
|
||||
endif()
|
||||
if(NOT MS2_ROOT_DIR)
|
||||
set(MS2_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mediastreamer2)
|
||||
endif()
|
||||
if(NOT MS2_INCLUDE_DIR)
|
||||
set(MS2_INCLUDE_DIR ${MS2_ROOT_DIR}/include)
|
||||
endif()
|
||||
if(NOT LIBXML2_ROOT_DIR)
|
||||
set(LIBXML2_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../libxml2)
|
||||
endif()
|
||||
if(NOT LIBXML2_INCLUDE_DIR)
|
||||
set(LIBXML2_INCLUDE_DIR ${LIBXML2_ROOT_DIR}/include)
|
||||
endif()
|
||||
if(NOT BELLESIP_ROOT_DIR)
|
||||
set(BELLESIP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../belle-sip)
|
||||
endif()
|
||||
if(NOT BELLESIP_INCLUDE_DIR)
|
||||
set(BELLESIP_INCLUDE_DIR ${BELLESIP_ROOT_DIR}/include)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
include/
|
||||
coreapi/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/coreapi/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../cmake/libxml2/
|
||||
)
|
||||
|
||||
if(USE_INSTALLED_COMPONENTS)
|
||||
include_directories(
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
${CMAKE_INSTALL_PREFIX}/include/libxml2
|
||||
)
|
||||
else()
|
||||
include_directories(
|
||||
${ORTP_INCLUDE_DIR}
|
||||
${MS2_INCLUDE_DIR}
|
||||
${LIBXML2_INCLUDE_DIR}
|
||||
${BELLESIP_INCLUDE_DIR}
|
||||
)
|
||||
if(WIN32)
|
||||
include_directories(${ORTP_ROOT_DIR}/build/vsx/oRTP/oRTP/)
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
add_subdirectory(coreapi)
|
||||
add_subdirectory(share)
|
||||
|
||||
if(INSTALL_COMPONENT_IN_POSTBUILD)
|
||||
add_install_target(INSTALL_liblinphone COMP_liblinphone liblinphone)
|
||||
endif()
|
||||
9
README
9
README
|
|
@ -44,11 +44,12 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol.
|
|||
$ sudo make install
|
||||
|
||||
+ Install zrtpcpp (optional), for unbreakable call encryption
|
||||
$ sudo apt-get install cmake libssl-dev
|
||||
$ git clone git://git.linphone.org/zrtpcpp.git
|
||||
$ cd zrtpcpp && cmake -Denable-ccrtp=false . && make
|
||||
$ sudo apt-get install cmake
|
||||
$ git clone https://github.com/wernerd/ZRTPCPP.git
|
||||
$ cd ZRTPCPP
|
||||
$ cmake -DCORE_LIB=true -DSDES=false . && make
|
||||
$ sudo make install
|
||||
|
||||
If you get this error: "cc1plus: error: unrecognized command line option ‘-std=c++11’", edit CMakeLists.txt and replace c++11 by c++0x .
|
||||
|
||||
- Compile linphone
|
||||
|
||||
|
|
|
|||
103
README.mingw
103
README.mingw
|
|
@ -9,7 +9,7 @@ In the feature list, select:
|
|||
* Mingw developer toolkit
|
||||
Let the installer fetch and install everything.
|
||||
|
||||
In mingw shell, run
|
||||
In mingw shell (also refered as msys), run
|
||||
|
||||
mingw-get install msys-zip
|
||||
mingw-get install msys-unzip
|
||||
|
|
@ -45,70 +45,63 @@ 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.
|
||||
|
||||
Get Linphone source code
|
||||
************************
|
||||
* Install msys-git from (http://code.google.com/p/msysgit/). 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://code.google.com/p/msysgit/). 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.
|
||||
|
||||
It is recommended that you create a directory somewhere with a path without any spaces or ~ characters, for example
|
||||
c:\sources\
|
||||
Within msys-git bash, do
|
||||
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
|
||||
git clone git://git.linphone.org/linphone.git --recursive
|
||||
|
||||
Building belle-sip
|
||||
******************
|
||||
* download the sources with msys-git shell using the following command:
|
||||
$ git clone git://git.linphone.org/belle-sip.git
|
||||
* compile and install
|
||||
$ ./autogen.sh
|
||||
$ ./configure --prefix=/usr --enable-shared --disable-static
|
||||
$ make && make install
|
||||
|
||||
Building
|
||||
********
|
||||
Building Linphone
|
||||
*****************
|
||||
|
||||
WARNING: During the build, windows might slow down suddenly. Using ctl+alt+del to start the windows system monitor,
|
||||
you might see a process 'LVpSRV.exe' or something like this that eats 90% of cpu.
|
||||
Kill it. Don't know what it is, but once killed, windows runs normally.
|
||||
* download the sources using the following command:
|
||||
$ git clone git://git.linphone.org/linphone.git --recursive
|
||||
|
||||
#Build linphone itself:
|
||||
#run autogen.sh after a git checkout or update
|
||||
* compile
|
||||
#always run autogen.sh after a git checkout or update
|
||||
$ ./autogen.sh
|
||||
|
||||
./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.
|
||||
|
||||
./configure --prefix=/usr --enable-shared --disable-static
|
||||
#note: in order to use the tunnel, append --enable-tunnel to the configure line above.
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
#compile:
|
||||
#Option: make a portable binary zip of linphone
|
||||
$ make zip
|
||||
|
||||
make
|
||||
#additionally you can make binary installer if you have Inno Setup 5 installed in its default path
|
||||
|
||||
#now install to /usr, required for compilation of plugins.
|
||||
$ make setup.exe
|
||||
#now you're done, you have a fresh linphone windows installer in the current directory.
|
||||
|
||||
make install
|
||||
Building plugins (optional)
|
||||
***************************
|
||||
|
||||
#make a binary zip of linphone
|
||||
|
||||
make zip
|
||||
|
||||
#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.
|
||||
|
||||
|
||||
|
||||
#build plugins
|
||||
cd mediastreamer2/plugins/msx264
|
||||
./autogen.sh
|
||||
PKG_CONFIG_PATH=/usr/lib/pkgconfig ./configure --prefix=/usr --enable-shared --disable-static
|
||||
#make a binary zip of this plugin
|
||||
make zip
|
||||
#or make an installer
|
||||
make setup.exe
|
||||
|
||||
#the buddylookup plugin enables lookup of buddies in a remote database using xml-rpc over http/https.
|
||||
cd coreapi/plugins/buddylookup
|
||||
./autogen.sh
|
||||
PKG_CONFIG_PATH=/usr/lib/pkgconfig ./configure --prefix=/usr --enable-shared --disable-static
|
||||
make
|
||||
#make a binary zip of this plugin
|
||||
make zip
|
||||
This the example for msx264 (H264 plugin), the same applies for other linphone plugins.
|
||||
$ cd mediastreamer2/plugins/msx264
|
||||
$ ./autogen.sh
|
||||
$ PKG_CONFIG_PATH=/usr/lib/pkgconfig ./configure --prefix=/usr --enable-shared --disable-static
|
||||
#make a binary zip of this plugin
|
||||
$ make zip
|
||||
#or make an installer
|
||||
$ make setup.exe
|
||||
|
||||
|
||||
******************************************************
|
||||
|
|
@ -161,14 +154,6 @@ When running "make install DESTDIR=<somepath>", somepath must be absolute and sh
|
|||
$ make install DESTDIR=/usr
|
||||
$ make install DESTDIR=/home/<myuser>/polarssl-install
|
||||
|
||||
- building belle-sip
|
||||
* download the sources with:
|
||||
$ git clone git://git.linphone.org/belle-sip.git
|
||||
* compile and install, assuming you have already compiled polarssl and antlr3c and installed in /.
|
||||
$ ./autogen.sh
|
||||
$ ./configure --prefix=/usr --enable-shared --disable-static
|
||||
$ make && make install && make install DESTDIR=/home/<myuser>/belle-sip-install
|
||||
|
||||
- building libsrtp
|
||||
* download the sources with
|
||||
$ git clone git://git.linphone.org/srtp.git
|
||||
|
|
|
|||
94
README.zrtp
94
README.zrtp
|
|
@ -1,94 +0,0 @@
|
|||
ZRTP guide
|
||||
|
||||
== Downloads ==
|
||||
- SRTP
|
||||
http://sourceforge.net/projects/srtp/
|
||||
or "apt-get source libsrtp0" on Debian
|
||||
|
||||
- ZRTP (libzrtpcpp-2.0)
|
||||
http://www.gnutelephony.org/index.php/GNU_ZRTP
|
||||
|
||||
|
||||
== Patch libzrtpcpp ==
|
||||
Index: src/ZIDFile.cpp
|
||||
===================================================================
|
||||
--- src/ZIDFile.cpp (révision 754)
|
||||
+++ src/ZIDFile.cpp (copie de travail)
|
||||
@@ -78,10 +78,11 @@
|
||||
|
||||
// create save file name, rename and re-open
|
||||
// if rename fails, just unlink old ZID file and create a brand new file
|
||||
- // just a little inconnvenience for the user, need to verify new SAS
|
||||
+ // just a little inconvenience for the user, need to verify new SAS
|
||||
std::string fn = std::string(name) + std::string(".save");
|
||||
if (rename(name, fn.c_str()) < 0) {
|
||||
- unlink(name);
|
||||
+ // unlink(name);
|
||||
createZIDFile(name);
|
||||
return;
|
||||
}
|
||||
Index: src/libzrtpcpp/ZrtpCallback.h
|
||||
===================================================================
|
||||
--- src/libzrtpcpp/ZrtpCallback.h (révision 754)
|
||||
+++ src/libzrtpcpp/ZrtpCallback.h (copie de travail)
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
-#include <commoncpp/config.h>
|
||||
+//#include <commoncpp/config.h>
|
||||
#include <libzrtpcpp/ZrtpCodes.h>
|
||||
|
||||
/**
|
||||
Index: src/libzrtpcpp/ZIDRecord.h
|
||||
===================================================================
|
||||
--- src/libzrtpcpp/ZIDRecord.h (révision 754)
|
||||
+++ src/libzrtpcpp/ZIDRecord.h (copie de travail)
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
-#include <commoncpp/config.h>
|
||||
+//#include <commoncpp/config.h>
|
||||
|
||||
#define IDENTIFIER_LEN 12
|
||||
#define RS_LENGTH 32
|
||||
Index: CMakeLists.txt
|
||||
===================================================================
|
||||
--- CMakeLists.txt (révision 754)
|
||||
+++ CMakeLists.txt (copie de travail)
|
||||
@@ -124,11 +124,15 @@
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
add_definitions(-Wno-long-long -Wno-char-subscripts)
|
||||
add_definitions(-Wall -ansi -pedantic)
|
||||
+ add_definitions(-DNEW_STDCPP)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
-add_subdirectory(demo)
|
||||
|
||||
+if (enable_ccrtp)
|
||||
+ add_subdirectory(demo)
|
||||
+endif()
|
||||
+
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package/)
|
||||
MESSAGE(STATUS "package dir not found")
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package/)
|
||||
|
||||
|
||||
|
||||
== Create simlinks or move folders ==
|
||||
submodules/external/srtp -> path_to_your_srtp_source
|
||||
submodules/external/libzrtpcpp -> path_to_your_patched_zrtpcpp_source
|
||||
|
||||
|
||||
|
||||
== Compilation for Android ==
|
||||
ndk-build BUILD_GPLV3_ZRTP=1 -j5
|
||||
|
||||
|
||||
== Compilation for Desktop version ==
|
||||
First ortp: ./autogen.sh && ./configure --enable-zrtp && make -j5 && sudo make install
|
||||
Then mediastreamer2: ./autogen.sh && ./configure && make -j5 && sudo make install
|
||||
Finally linphone: ./autogen.sh && ./configure --enable-external-ortp && make -j5 && sudo make install
|
||||
|
||||
|
|
@ -60,7 +60,8 @@ LOCAL_SRC_FILES := \
|
|||
linphone_tunnel_config.c \
|
||||
message_storage.c \
|
||||
info.c \
|
||||
event.c
|
||||
event.c \
|
||||
xml.c
|
||||
|
||||
ifndef LINPHONE_VERSION
|
||||
LINPHONE_VERSION = "Devel"
|
||||
|
|
|
|||
13
build/redhat/INSTALL
Normal file
13
build/redhat/INSTALL
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
INSTALL :
|
||||
|
||||
Download and install the repo rpmforge :
|
||||
http://repoforge.org/use/
|
||||
|
||||
$ sudo rpm -Uvh <path to rpmforge rpm>
|
||||
|
||||
Download the linphone-release rpm
|
||||
$ sudo rpm -Uvh <path to linphone rpm>
|
||||
|
||||
$ sudo yum install linphone
|
||||
|
||||
|
||||
57
build/redhat/README
Normal file
57
build/redhat/README
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
**********************************
|
||||
* Compiling linphone on RedHat *
|
||||
**********************************
|
||||
|
||||
Download and install the repo rpmforge :
|
||||
http://repoforge.org/use/
|
||||
|
||||
$ sudo rpm -Uhv <path to rpmforge rpm>
|
||||
$ yum -y update
|
||||
|
||||
- Install build time dependencies
|
||||
$ sudo yum install libtool intltool
|
||||
|
||||
- Install others dependencies
|
||||
$ sudo yum install gtk2-devel
|
||||
$ sudo yum install ffmpeg-devel
|
||||
$ sudo yum install openldap-devel
|
||||
|
||||
- Download and install packages
|
||||
$ sudo rpm -Uhv ftp://ftp.icm.edu.pl/vol/rzm2/linux-fedora/linux/epel/6/x86_64/polarssl-1.3.2-1.el6.x86_64.rpm
|
||||
$ sudo rpm -Uvh ftp://ftp.icm.edu.pl/vol/rzm2/linux-fedora/linux/epel/6/x86_64/polarssl-devel-1.3.2-1.el6.x86_64.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Everything/x86_64/os/Packages/antlr3-C-3.2-14.fc15.x86_64.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Everything/x86_64/os/Packages/antlr3-C-devel-3.2-14.fc15.x86_64.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Everything/x86_64/os/Packages/antlr3-tool-3.2-14.fc15.noarch.rpm
|
||||
$ sudo rpm -Uhv ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/15/Fedora/i386/os/Packages/antlr3-java-3.2-14.fc15.noarch.rpm
|
||||
|
||||
- Git repository
|
||||
|
||||
Belle-sip : git clone git://git.linphone.org/belle-sip.git
|
||||
oRTP : git clone git://git.linphone.org/ortp.git
|
||||
Mediastreamer : git clone git://git.linphone.org/mediastreamer2.git
|
||||
|
||||
- Compile Belle-sip / oRTP / mediastreamer
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make && make rpm
|
||||
$ sudo rpm -Uvh <path to rpm and rpm-devel>
|
||||
|
||||
- Compile Linphone
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make && make rpm
|
||||
|
||||
|
||||
-Create yum repo :
|
||||
$ cd rpmbuild/RPMS/*arch*/
|
||||
$ createrepo .
|
||||
|
||||
Create a file "linphone-release.repo" in /etc/yum.repos.d/ with :
|
||||
|
||||
[linphone-release]
|
||||
name = Linphone for redhat
|
||||
baseurl = file/// *path to the new repo*
|
||||
enabled = 1
|
||||
gpgcheck = 0
|
||||
|
||||
$ sudo yum install linphone
|
||||
|
|
@ -117,7 +117,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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>__STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;_XKEYCHECK_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
|
|
@ -147,7 +147,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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>__STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;_XKEYCHECK_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
|
@ -207,6 +207,7 @@
|
|||
<ClCompile Include="..\..\..\coreapi\siplogin.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\sipsetup.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\TunnelManager.cc" />
|
||||
<ClCompile Include="..\..\..\coreapi\xml.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\coreapi\bellesip_sal\sal_impl.h" />
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ COMMON_CFLAGS=\
|
|||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(VIDEO_CFLAGS) \
|
||||
$(READLINE_CFLAGS) \
|
||||
$(SQLITE3_CFLAGS)
|
||||
$(SQLITE3_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
if BUILD_CONSOLE
|
||||
|
||||
|
|
@ -29,7 +30,8 @@ linphonec_LDADD=$(top_builddir)/coreapi/liblinphone.la \
|
|||
$(READLINE_LIBS) \
|
||||
$(SQLITE3_LIBS) \
|
||||
$(X11_LIBS) \
|
||||
$(BELLESIP_LIBS)
|
||||
$(BELLESIP_LIBS) \
|
||||
$(LIBXML2_LIBS)
|
||||
|
||||
if BUILD_WIN32
|
||||
#special build of linphonec to detach from the windows console
|
||||
|
|
|
|||
140
coreapi/CMakeLists.txt
Normal file
140
coreapi/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
find_program(GIT git)
|
||||
|
||||
set(GIT_VERSION "unknown")
|
||||
if(GIT)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${GIT} describe --always
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${GIT} describe --abbrev=0
|
||||
OUTPUT_VARIABLE GIT_TAG
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${GIT} rev-parse HEAD
|
||||
OUTPUT_VARIABLE GIT_REVISION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(GIT_DESCRIBE)
|
||||
set(GIT_VERSION ${GIT_DESCRIBE})
|
||||
else(GIT_DESCRIBE)
|
||||
if(GIT_REVISION)
|
||||
set(GIT_VERSION ${GIT_REVISION})
|
||||
endif(GIT_REVISION)
|
||||
endif(GIT_DESCRIBE)
|
||||
endif(GIT)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "#define LIBLINPHONE_GIT_VERSION \"${GIT_VERSION}\""
|
||||
OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
address.c
|
||||
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_publish.c
|
||||
bellesip_sal/sal_op_registration.c
|
||||
bellesip_sal/sal_sdp.c
|
||||
callbacks.c
|
||||
chat.c
|
||||
conference.c
|
||||
ec-calibrator.c
|
||||
enum.c
|
||||
event.c
|
||||
friend.c
|
||||
info.c
|
||||
linphonecall.c
|
||||
linphonecore.c
|
||||
#linphone_tunnel.cc
|
||||
linphone_tunnel_stubs.c
|
||||
linphone_tunnel_config.c
|
||||
lpconfig.c
|
||||
lsd.c
|
||||
message_storage.c
|
||||
misc.c
|
||||
offeranswer.c
|
||||
presence.c
|
||||
proxy.c
|
||||
sal.c
|
||||
siplogin.c
|
||||
sipsetup.c
|
||||
#TunnelManager.cc
|
||||
xml.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
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-D_TRUE_TIME
|
||||
-DIN_LINPHONE
|
||||
-DUSE_BELLESIP
|
||||
#-DTUNNEL_ENABLED
|
||||
#-DVIDEO_ENABLED
|
||||
-DLINPHONE_PACKAGE_NAME="linphone"
|
||||
-DLINPHONE_VERSION="Devel"
|
||||
-DLIBLINPHONE_EXPORTS
|
||||
-DLINPHONE_PLUGINS_DIR=""
|
||||
)
|
||||
|
||||
if(LINPHONE_ENABLE_VIDEO)
|
||||
add_definitions(-DVIDEO_ENABLED)
|
||||
endif(LINPHONE_ENABLE_VIDEO)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(
|
||||
-DWINDOW_NATIVE
|
||||
/FIliblinphone_gitversion.h
|
||||
)
|
||||
|
||||
set(LIBS ws2_32)
|
||||
endif(WIN32)
|
||||
set(LIBS ${LIBS} libortp libmediastreamer_base libmediastreamer_voip libbellesip libxml2)
|
||||
|
||||
add_library(liblinphone SHARED ${SOURCE_FILES})
|
||||
set_target_properties(liblinphone PROPERTIES VERSION 3.6.99 SOVERSION 5)
|
||||
|
||||
target_link_libraries(liblinphone ${LIBS})
|
||||
|
||||
install(TARGETS liblinphone
|
||||
COMPONENT COMP_liblinphone
|
||||
DESTINATION ${LIB_INSTALL_DIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
||||
if(USE_INSTALLED_COMPONENTS)
|
||||
add_dependencies(liblinphone
|
||||
INSTALL_libortp
|
||||
INSTALL_libmediastreamer2
|
||||
INSTALL_libbellesip
|
||||
INSTALL_libxml2)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
file(GLOB HEADER_FILES "*.h")
|
||||
|
||||
install(FILES ${HEADER_FILES}
|
||||
COMPONENT COMP_liblinphone
|
||||
DESTINATION include/linphone
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
|
|
@ -51,6 +51,7 @@ liblinphone_la_SOURCES=\
|
|||
contactprovider.c contactprovider.h contact_providers_priv.h \
|
||||
ldap/ldapprovider.c ldap/ldapprovider.h \
|
||||
dict.c \
|
||||
xml.c \
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
if BUILD_UPNP
|
||||
|
|
|
|||
|
|
@ -464,6 +464,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
|
|||
ctx->callbacks.subscribe_presence_received=(SalOnSubscribePresenceReceived)unimplemented_stub;
|
||||
if (ctx->callbacks.text_received==NULL)
|
||||
ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
|
||||
if (ctx->callbacks.is_composing_received==NULL)
|
||||
ctx->callbacks.is_composing_received=(SalOnIsComposingReceived)unimplemented_stub;
|
||||
if (ctx->callbacks.ping_reply==NULL)
|
||||
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
|
||||
if (ctx->callbacks.auth_requested==NULL)
|
||||
|
|
@ -915,5 +917,12 @@ unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size){
|
|||
return belle_sip_random_bytes(ret,size);
|
||||
}
|
||||
|
||||
belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name) {
|
||||
belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(sal->stack);
|
||||
return belle_sip_main_loop_create_timeout(ml, func, data, timeout_value_ms, timer_name);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "sal_impl.h"
|
||||
#include "offeranswer.h"
|
||||
|
||||
static int extract_sdp(belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error);
|
||||
|
||||
/*used for calls terminated before creation of a dialog*/
|
||||
static void call_set_released(SalOp* op){
|
||||
if (!op->call_released){
|
||||
|
|
@ -84,8 +86,8 @@ static void sdp_process(SalOp *h){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) {
|
||||
belle_sip_header_content_type_t* content_type ;
|
||||
belle_sip_header_content_length_t* content_length;
|
||||
|
|
@ -159,10 +161,13 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat
|
|||
|
||||
static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
|
||||
belle_sdp_session_description_t* sdp;
|
||||
if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(response)))) {
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
if (op->base.local_media) sdp_process(op);
|
||||
SalReason reason;
|
||||
if (extract_sdp(BELLE_SIP_MESSAGE(response),&sdp,&reason)==0) {
|
||||
if (sdp){
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
if (op->base.local_media) sdp_process(op);
|
||||
}/*if no sdp in response, what can we do ?*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,15 +327,61 @@ static void unsupported_method(belle_sip_server_transaction_t* server_transactio
|
|||
return;
|
||||
}
|
||||
|
||||
static void process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
|
||||
/*
|
||||
* Extract the sdp from a sip message.
|
||||
* If there is no body in the message, the session_desc is set to null, 0 is returned.
|
||||
* If body was present is not a SDP or parsing of SDP failed, -1 is returned and SalReason is set appropriately.
|
||||
*
|
||||
**/
|
||||
static int extract_sdp(belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error) {
|
||||
belle_sip_header_content_type_t* 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));
|
||||
if (*session_desc==NULL) {
|
||||
ms_error("Failed to parse SDP message.");
|
||||
*error=SalReasonNotAcceptable;
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
*error=SalReasonUnsupportedContent;
|
||||
return -1;
|
||||
}
|
||||
}else *session_desc=NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_media_description_acceptable(SalMediaDescription *md){
|
||||
if (md->n_total_streams==0){
|
||||
ms_warning("Media description does not define any stream.");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
|
||||
belle_sdp_session_description_t* sdp;
|
||||
if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(invite)))) {
|
||||
op->sdp_offering=FALSE;
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
belle_sip_object_unref(sdp);
|
||||
}else
|
||||
op->sdp_offering=TRUE;
|
||||
int err=0;
|
||||
SalReason reason;
|
||||
if (extract_sdp(BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) {
|
||||
if (sdp){
|
||||
op->sdp_offering=FALSE;
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
/*make some sanity check about the SDP received*/
|
||||
if (!is_media_description_acceptable(op->base.remote_media)){
|
||||
err=-1;
|
||||
reason=SalReasonNotAcceptable;
|
||||
}
|
||||
belle_sip_object_unref(sdp);
|
||||
}else op->sdp_offering=TRUE; /*INVITE without SDP*/
|
||||
}else err=-1;
|
||||
|
||||
if (err==-1){
|
||||
sal_call_decline(op,reason,NULL);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
|
||||
|
|
@ -415,13 +466,18 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
/*great ACK received*/
|
||||
if (strcmp("ACK",belle_sip_request_get_method(req))==0) {
|
||||
if (op->sdp_offering){
|
||||
if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(req)))){
|
||||
if (op->base.remote_media)
|
||||
sal_media_description_unref(op->base.remote_media);
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
sdp_process(op);
|
||||
belle_sip_object_unref(sdp);
|
||||
SalReason reason;
|
||||
if (extract_sdp(BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){
|
||||
if (sdp){
|
||||
if (op->base.remote_media)
|
||||
sal_media_description_unref(op->base.remote_media);
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
sdp_process(op);
|
||||
belle_sip_object_unref(sdp);
|
||||
}else{
|
||||
ms_warning("SDP expected in ACK but not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*FIXME
|
||||
|
|
@ -445,9 +501,8 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
sal_media_description_unref(op->result);
|
||||
op->result=NULL;
|
||||
}
|
||||
process_sdp_for_invite(op,req);
|
||||
|
||||
op->base.root->callbacks.call_updating(op);
|
||||
if (process_sdp_for_invite(op,req)==0)
|
||||
op->base.root->callbacks.call_updating(op);
|
||||
} else if (strcmp("INFO",belle_sip_request_get_method(req))==0){
|
||||
if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))
|
||||
&& strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) {
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ SalReason sal_reason_to_sip_code(SalReason r){
|
|||
case SalReasonForbidden:
|
||||
ret=403;
|
||||
break;
|
||||
case SalReasonMedia:
|
||||
case SalReasonUnsupportedContent:
|
||||
ret=415;
|
||||
break;
|
||||
case SalReasonNotFound:
|
||||
|
|
@ -356,7 +356,7 @@ SalReason sal_reason_to_sip_code(SalReason r){
|
|||
ret=401;
|
||||
break;
|
||||
case SalReasonNotAcceptable:
|
||||
ret=488;
|
||||
ret=488; /*or maybe 606 Not Acceptable ?*/
|
||||
break;
|
||||
case SalReasonNoMatch:
|
||||
ret=481;
|
||||
|
|
@ -385,7 +385,7 @@ void sal_compute_sal_errors_from_code(int code ,SalError* sal_err,SalReason* sal
|
|||
break;
|
||||
case 415:
|
||||
*sal_err=SalErrorFailure;
|
||||
*sal_reason=SalReasonMedia;
|
||||
*sal_reason=SalReasonUnsupportedContent;
|
||||
break;
|
||||
case 422:
|
||||
ms_error ("422 not implemented yet");;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ static bool_t is_external_body(belle_sip_header_content_type_t* content_type) {
|
|||
return strcmp("message",belle_sip_header_content_type_get_type(content_type))==0
|
||||
&& strcmp("external-body",belle_sip_header_content_type_get_subtype(content_type))==0;
|
||||
}
|
||||
static bool_t is_im_iscomposing(belle_sip_header_content_type_t* content_type) {
|
||||
return strcmp("application",belle_sip_header_content_type_get_type(content_type))==0
|
||||
&& strcmp("im-iscomposing+xml",belle_sip_header_content_type_get_subtype(content_type))==0;
|
||||
}
|
||||
|
||||
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
|
||||
SalOp* op = (SalOp*)op_base;
|
||||
|
|
@ -88,8 +92,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
belle_sip_header_call_id_t* call_id = belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
|
||||
belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
|
||||
belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t);
|
||||
SalMessage salmsg;
|
||||
char message_id[256]={0};
|
||||
int response_code=501;
|
||||
char* from;
|
||||
bool_t plain_text=FALSE;
|
||||
|
|
@ -99,7 +101,8 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
|
||||
if (content_type && ((plain_text=is_plain_text(content_type))
|
||||
|| (external_body=is_external_body(content_type)))) {
|
||||
|
||||
SalMessage salmsg;
|
||||
char message_id[256]={0};
|
||||
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)));
|
||||
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
|
||||
|
|
@ -121,6 +124,17 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
belle_sip_free(from);
|
||||
if (salmsg.url) ms_free((char*)salmsg.url);
|
||||
response_code=200;
|
||||
} else if (content_type && is_im_iscomposing(content_type)) {
|
||||
SalIsComposing saliscomposing;
|
||||
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)));
|
||||
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address));
|
||||
saliscomposing.from=from;
|
||||
saliscomposing.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
|
||||
op->base.root->callbacks.is_composing_received(op,&saliscomposing);
|
||||
belle_sip_object_unref(address);
|
||||
belle_sip_free(from);
|
||||
response_code=200;
|
||||
} else {
|
||||
ms_error("Unsupported MESSAGE with content type [%s/%s]",belle_sip_header_content_type_get_type(content_type)
|
||||
,belle_sip_header_content_type_get_subtype(content_type));
|
||||
|
|
|
|||
|
|
@ -612,7 +612,8 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,msg600);
|
||||
break;
|
||||
case SalReasonMedia:
|
||||
case SalReasonUnsupportedContent: /*<this is for compatibility: linphone sent 415 because of SDP offer answer failure*/
|
||||
case SalReasonNotAcceptable:
|
||||
//media_encryption_mandatory
|
||||
if (call->params.media_encryption == LinphoneMediaEncryptionSRTP &&
|
||||
!linphone_core_is_media_encryption_mandatory(lc)) {
|
||||
|
|
@ -843,6 +844,11 @@ static void text_received(SalOp *op, const SalMessage *msg){
|
|||
}
|
||||
}
|
||||
|
||||
static void is_composing_received(SalOp *op, const SalIsComposing *is_composing) {
|
||||
LinphoneCore *lc = (LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
linphone_core_is_composing_received(lc, op, is_composing);
|
||||
}
|
||||
|
||||
static void parse_presence_requested(SalOp *op, const char *content_type, const char *content_subtype, const char *body, SalPresenceModel **result) {
|
||||
linphone_notify_parse_presence(op, content_type, content_subtype, body, result);
|
||||
}
|
||||
|
|
@ -1001,8 +1007,14 @@ static int op_equals(LinphoneCall *a, SalOp *b) {
|
|||
|
||||
static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
|
||||
LinphoneChatMessage *chat_msg=(LinphoneChatMessage* )sal_op_get_user_pointer(op);
|
||||
const MSList* calls = linphone_core_get_calls(chat_msg->chat_room->lc);
|
||||
|
||||
const MSList* calls;
|
||||
|
||||
if (chat_msg == NULL) {
|
||||
// Do not handle delivery status for isComposing messages.
|
||||
return;
|
||||
}
|
||||
calls = linphone_core_get_calls(chat_msg->chat_room->lc);
|
||||
|
||||
chat_msg->state=chatStatusSal2Linphone(status);
|
||||
linphone_chat_message_store_state(chat_msg);
|
||||
if (chat_msg && chat_msg->cb) {
|
||||
|
|
@ -1123,6 +1135,7 @@ SalCallbacks linphone_sal_callbacks={
|
|||
refer_received,
|
||||
text_received,
|
||||
text_delivery_update,
|
||||
is_composing_received,
|
||||
notify_refer,
|
||||
subscribe_received,
|
||||
subscribe_closed,
|
||||
|
|
|
|||
250
coreapi/chat.c
250
coreapi/chat.c
|
|
@ -26,6 +26,12 @@
|
|||
#include "private.h"
|
||||
#include "lpconfig.h"
|
||||
|
||||
#include <libxml/xmlwriter.h>
|
||||
|
||||
#define COMPOSING_DEFAULT_IDLE_TIMEOUT 15
|
||||
#define COMPOSING_DEFAULT_REFRESH_TIMEOUT 60
|
||||
#define COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT 120
|
||||
|
||||
/**
|
||||
* @addtogroup chatroom
|
||||
* @{
|
||||
|
|
@ -85,13 +91,40 @@ LinphoneChatRoom* linphone_core_get_or_create_chat_room(LinphoneCore* lc, const
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr) {
|
||||
if (cr->composing_idle_timer) {
|
||||
sal_cancel_timer(cr->lc->sal, cr->composing_idle_timer);
|
||||
belle_sip_object_unref(cr->composing_idle_timer);
|
||||
cr->composing_idle_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *cr) {
|
||||
if (cr->composing_refresh_timer) {
|
||||
sal_cancel_timer(cr->lc->sal, cr->composing_refresh_timer);
|
||||
belle_sip_object_unref(cr->composing_refresh_timer);
|
||||
cr->composing_refresh_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_chat_room_delete_remote_composing_refresh_timer(LinphoneChatRoom *cr) {
|
||||
if (cr->remote_composing_refresh_timer) {
|
||||
sal_cancel_timer(cr->lc->sal, cr->remote_composing_refresh_timer);
|
||||
belle_sip_object_unref(cr->remote_composing_refresh_timer);
|
||||
cr->remote_composing_refresh_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a LinphoneChatRoom.
|
||||
* @param cr #LinphoneChatRoom object
|
||||
*/
|
||||
void linphone_chat_room_destroy(LinphoneChatRoom *cr){
|
||||
LinphoneCore *lc=cr->lc;
|
||||
linphone_chat_room_delete_composing_idle_timer(cr);
|
||||
linphone_chat_room_delete_composing_refresh_timer(cr);
|
||||
linphone_chat_room_delete_remote_composing_refresh_timer(cr);
|
||||
lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr);
|
||||
linphone_address_destroy(cr->peer_url);
|
||||
ms_free(cr->peer);
|
||||
|
|
@ -142,6 +175,12 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
|
|||
msg->dir=LinphoneChatMessageOutgoing;
|
||||
msg->from=linphone_address_new(identity);
|
||||
msg->storage_id=linphone_chat_message_store(msg);
|
||||
|
||||
if (cr->is_composing == LinphoneIsComposingActive) {
|
||||
cr->is_composing = LinphoneIsComposingIdle;
|
||||
}
|
||||
linphone_chat_room_delete_composing_idle_timer(cr);
|
||||
linphone_chat_room_delete_composing_refresh_timer(cr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,7 +198,10 @@ void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc,
|
|||
//legacy API
|
||||
if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, msg->from, msg->message);
|
||||
if (lc->vtable.message_received!=NULL) lc->vtable.message_received(lc, cr,msg);
|
||||
|
||||
if (cr->lc->vtable.is_composing_received != NULL) {
|
||||
cr->remote_is_composing = LinphoneIsComposingIdle;
|
||||
cr->lc->vtable.is_composing_received(cr->lc, cr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -225,6 +267,85 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
ms_free(from);
|
||||
}
|
||||
|
||||
static int linphone_chat_room_remote_refresh_composing_expired(void *data, unsigned int revents) {
|
||||
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
|
||||
belle_sip_object_unref(cr->remote_composing_refresh_timer);
|
||||
cr->remote_composing_refresh_timer = NULL;
|
||||
cr->remote_is_composing = LinphoneIsComposingIdle;
|
||||
if (cr->lc->vtable.is_composing_received != NULL)
|
||||
cr->lc->vtable.is_composing_received(cr->lc, cr);
|
||||
return BELLE_SIP_STOP;
|
||||
}
|
||||
|
||||
static const char *iscomposing_prefix = "/xsi:isComposing";
|
||||
|
||||
static void process_im_is_composing_notification(LinphoneChatRoom *cr, xmlparsing_context_t *xml_ctx) {
|
||||
char xpath_str[MAX_XPATH_LENGTH];
|
||||
xmlXPathObjectPtr iscomposing_object;
|
||||
const char *state_str = NULL;
|
||||
const char *refresh_str = NULL;
|
||||
int refresh_duration = lp_config_get_int(cr->lc->config, "sip", "composing_remote_refresh_timeout", COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT);
|
||||
int i;
|
||||
LinphoneIsComposingState state = LinphoneIsComposingIdle;
|
||||
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0) return;
|
||||
|
||||
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"xsi", (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing");
|
||||
iscomposing_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, iscomposing_prefix);
|
||||
if ((iscomposing_object != NULL) && (iscomposing_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= iscomposing_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/xsi:state", iscomposing_prefix, i);
|
||||
state_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (state_str == NULL) continue;
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/xsi:refresh", iscomposing_prefix, i);
|
||||
refresh_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
}
|
||||
}
|
||||
|
||||
if (state_str != NULL) {
|
||||
if (strcmp(state_str, "active") == 0) {
|
||||
state = LinphoneIsComposingActive;
|
||||
if (refresh_str != NULL) {
|
||||
refresh_duration = atoi(refresh_str);
|
||||
}
|
||||
if (!cr->remote_composing_refresh_timer) {
|
||||
cr->remote_composing_refresh_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_remote_refresh_composing_expired, cr, refresh_duration * 1000, "composing remote refresh timeout");
|
||||
} else {
|
||||
belle_sip_source_set_timeout(cr->remote_composing_refresh_timer, refresh_duration * 1000);
|
||||
}
|
||||
} else {
|
||||
linphone_chat_room_delete_remote_composing_refresh_timer(cr);
|
||||
}
|
||||
|
||||
cr->remote_is_composing = state;
|
||||
if (cr->lc->vtable.is_composing_received != NULL)
|
||||
cr->lc->vtable.is_composing_received(cr->lc, cr);
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_chat_room_notify_is_composing(LinphoneChatRoom *cr, const char *text) {
|
||||
xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
|
||||
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
|
||||
xml_ctx->doc = xmlReadDoc((const unsigned char*)text, 0, NULL, 0);
|
||||
if (xml_ctx->doc != NULL) {
|
||||
process_im_is_composing_notification(cr, xml_ctx);
|
||||
} else {
|
||||
ms_warning("Wrongly formatted presence XML: %s", xml_ctx->errorBuffer);
|
||||
}
|
||||
linphone_xmlparsing_context_destroy(xml_ctx);
|
||||
}
|
||||
|
||||
void linphone_core_is_composing_received(LinphoneCore *lc, SalOp *op, const SalIsComposing *is_composing) {
|
||||
LinphoneChatRoom *cr = linphone_core_get_or_create_chat_room(lc, is_composing->from);
|
||||
if (cr != NULL) {
|
||||
linphone_chat_room_notify_is_composing(cr, is_composing->text);
|
||||
}
|
||||
}
|
||||
|
||||
bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr) {
|
||||
return (cr->remote_is_composing == LinphoneIsComposingActive) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns back pointer to LinphoneCore object.
|
||||
**/
|
||||
|
|
@ -319,6 +440,131 @@ void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage*
|
|||
_linphone_chat_room_send_message(cr, msg);
|
||||
}
|
||||
|
||||
static char * linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) {
|
||||
xmlBufferPtr buf;
|
||||
xmlTextWriterPtr writer;
|
||||
int err;
|
||||
char *content = NULL;
|
||||
|
||||
buf = xmlBufferCreate();
|
||||
if (buf == NULL) {
|
||||
ms_error("Error creating the XML buffer");
|
||||
return content;
|
||||
}
|
||||
writer = xmlNewTextWriterMemory(buf, 0);
|
||||
if (writer == NULL) {
|
||||
ms_error("Error creating the XML writer");
|
||||
return content;
|
||||
}
|
||||
|
||||
err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"isComposing", (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing");
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"xsi",
|
||||
NULL, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance");
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xsi", (const xmlChar *)"schemaLocation",
|
||||
NULL, (const xmlChar *)"urn:ietf:params:xml:ns:im-composing iscomposing.xsd");
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"state",
|
||||
(cr->is_composing == LinphoneIsComposingActive) ? (const xmlChar *)"active" : (const xmlChar *)"idle");
|
||||
}
|
||||
if ((err >= 0) && (cr->is_composing == LinphoneIsComposingActive)) {
|
||||
char refresh_str[4] = { 0 };
|
||||
int refresh_timeout = lp_config_get_int(cr->lc->config, "sip", "composing_refresh_timeout", COMPOSING_DEFAULT_REFRESH_TIMEOUT);
|
||||
snprintf(refresh_str, sizeof(refresh_str), "%u", refresh_timeout);
|
||||
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"refresh", (const xmlChar *)refresh_str);
|
||||
}
|
||||
if (err >= 0) {
|
||||
/* Close the "isComposing" element. */
|
||||
err = xmlTextWriterEndElement(writer);
|
||||
}
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterEndDocument(writer);
|
||||
}
|
||||
if (err > 0) {
|
||||
/* xmlTextWriterEndDocument returns the size of the content. */
|
||||
content = ms_strdup((char *)buf->content);
|
||||
}
|
||||
xmlFreeTextWriter(writer);
|
||||
xmlBufferFree(buf);
|
||||
return content;
|
||||
}
|
||||
|
||||
static void linphone_chat_room_send_is_composing_notification(LinphoneChatRoom *cr) {
|
||||
SalOp *op = NULL;
|
||||
LinphoneCall *call;
|
||||
const char *identity = NULL;
|
||||
char *content = NULL;
|
||||
|
||||
if (lp_config_get_int(cr->lc->config, "sip", "chat_use_call_dialogs", 0)) {
|
||||
if ((call = linphone_core_get_call_by_remote_address(cr->lc, cr->peer)) != NULL) {
|
||||
if (call->state == LinphoneCallConnected ||
|
||||
call->state == LinphoneCallStreamsRunning ||
|
||||
call->state == LinphoneCallPaused ||
|
||||
call->state == LinphoneCallPausing ||
|
||||
call->state == LinphoneCallPausedByRemote) {
|
||||
ms_message("send SIP message through the existing call.");
|
||||
op = call->op;
|
||||
identity = linphone_core_find_best_identity(cr->lc, linphone_call_get_remote_address(call));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (op == NULL) {
|
||||
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(cr->lc, cr->peer_url);
|
||||
if (proxy)
|
||||
identity = linphone_proxy_config_get_identity(proxy);
|
||||
else
|
||||
identity = linphone_core_get_primary_contact(cr->lc);
|
||||
/*sending out of calls*/
|
||||
op = sal_op_new(cr->lc->sal);
|
||||
linphone_configure_op(cr->lc, op, cr->peer_url, NULL, lp_config_get_int(cr->lc->config, "sip", "chat_msg_with_contact", 0));
|
||||
}
|
||||
content = linphone_chat_room_create_is_composing_xml(cr);
|
||||
if (content != NULL) {
|
||||
sal_message_send(op, identity, cr->peer, "application/im-iscomposing+xml", content);
|
||||
ms_free(content);
|
||||
}
|
||||
}
|
||||
|
||||
static int linphone_chat_room_stop_composing(void *data, unsigned int revents) {
|
||||
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
|
||||
cr->is_composing = LinphoneIsComposingIdle;
|
||||
linphone_chat_room_send_is_composing_notification(cr);
|
||||
linphone_chat_room_delete_composing_refresh_timer(cr);
|
||||
belle_sip_object_unref(cr->composing_idle_timer);
|
||||
cr->composing_idle_timer = NULL;
|
||||
return BELLE_SIP_STOP;
|
||||
}
|
||||
|
||||
static int linphone_chat_room_refresh_composing(void *data, unsigned int revents) {
|
||||
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
|
||||
linphone_chat_room_send_is_composing_notification(cr);
|
||||
return BELLE_SIP_CONTINUE;
|
||||
}
|
||||
|
||||
void linphone_chat_room_compose(LinphoneChatRoom *cr) {
|
||||
int idle_timeout = lp_config_get_int(cr->lc->config, "sip", "composing_idle_timeout", COMPOSING_DEFAULT_IDLE_TIMEOUT);
|
||||
int refresh_timeout = lp_config_get_int(cr->lc->config, "sip", "composing_refresh_timeout", COMPOSING_DEFAULT_REFRESH_TIMEOUT);
|
||||
if (cr->is_composing == LinphoneIsComposingIdle) {
|
||||
cr->is_composing = LinphoneIsComposingActive;
|
||||
linphone_chat_room_send_is_composing_notification(cr);
|
||||
if (!cr->composing_refresh_timer) {
|
||||
cr->composing_refresh_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_refresh_composing, cr, refresh_timeout * 1000, "composing refresh timeout");
|
||||
} else {
|
||||
belle_sip_source_set_timeout(cr->composing_refresh_timer, refresh_timeout * 1000);
|
||||
}
|
||||
if (!cr->composing_idle_timer) {
|
||||
cr->composing_idle_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_stop_composing, cr, idle_timeout * 1000, "composing idle timeout");
|
||||
}
|
||||
}
|
||||
belle_sip_source_set_timeout(cr->composing_idle_timer, idle_timeout * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a #LinphoneChatMessageState as a string.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef CONTACT_PROVIDERS_PRIV_H
|
||||
#define CONTACT_PROVIDERS_PRIV_H
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include "private.h"
|
||||
#include "linphonecore.h"
|
||||
|
||||
/* Base for contact search and contact provider */
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ int linphone_contact_search_compare(const void* a, const void* b) {
|
|||
return !(ra->id == rb->id); // return 0 if id is equal, 1 otherwise
|
||||
}
|
||||
|
||||
LinphoneContactSearch*linphone_ldap_contact_search_ref(void* obj)
|
||||
LinphoneContactSearch*linphone_contact_search_ref(void* obj)
|
||||
{
|
||||
return LINPHONE_CONTACT_SEARCH(belle_sip_object_ref(obj));
|
||||
}
|
||||
|
|
@ -136,4 +136,3 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(LinphoneContactProvider)
|
|||
NULL, /* begin_search -> pure virtual */
|
||||
NULL /* cancel_search -> pure virtual */
|
||||
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
|
||||
|
||||
|
|
|
|||
|
|
@ -280,5 +280,11 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,5 +202,13 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr) {
|
||||
if (cr.isRemoteComposing())
|
||||
write("Remote is writing a message");
|
||||
else
|
||||
write("Remote has stop writing");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,5 +206,11 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,6 +237,12 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -595,9 +595,14 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
linphone_call_init_common(call, from, to);
|
||||
call->log->call_id=ms_strdup(sal_op_get_call_id(op)); /*must be known at that time*/
|
||||
linphone_core_init_default_params(lc, &call->params);
|
||||
|
||||
/*
|
||||
* Initialize call parameters according to incoming call parameters. This is to avoid to ask later (during reINVITEs) for features that the remote
|
||||
* end apparently does not support. This features are: privacy, video
|
||||
*/
|
||||
/*set privacy*/
|
||||
call->current_params.privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op);
|
||||
|
||||
/*set video support */
|
||||
md=sal_call_get_remote_media_description(op);
|
||||
call->params.has_video &= !!lc->video_policy.automatically_accept;
|
||||
if (md) {
|
||||
|
|
@ -605,6 +610,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
// In this case WE chose the media parameters according to policy.
|
||||
call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
|
||||
}
|
||||
|
||||
switch (linphone_core_get_firewall_policy(call->core)) {
|
||||
case LinphonePolicyUseIce:
|
||||
call->ice_session = ice_session_new();
|
||||
|
|
@ -1760,21 +1766,20 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
|
|||
|
||||
/* valid local tags are > 0 */
|
||||
if (stream->proto == SalProtoRtpSavp) {
|
||||
local_st_desc=sal_media_description_find_stream(call->localdesc,
|
||||
SalProtoRtpSavp,SalAudio);
|
||||
crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag);
|
||||
local_st_desc=sal_media_description_find_stream(call->localdesc,SalProtoRtpSavp,SalAudio);
|
||||
crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag);
|
||||
|
||||
if (crypto_idx >= 0) {
|
||||
audio_stream_enable_srtp(
|
||||
call->audiostream,
|
||||
stream->crypto[0].algo,
|
||||
local_st_desc->crypto[crypto_idx].master_key,
|
||||
stream->crypto[0].master_key);
|
||||
call->audiostream_encrypted=TRUE;
|
||||
} else {
|
||||
ms_warning("Failed to find local crypto algo with tag: %d", stream->crypto_local_tag);
|
||||
call->audiostream_encrypted=FALSE;
|
||||
}
|
||||
if (crypto_idx >= 0) {
|
||||
audio_stream_enable_srtp(
|
||||
call->audiostream,
|
||||
stream->crypto[0].algo,
|
||||
local_st_desc->crypto[crypto_idx].master_key,
|
||||
stream->crypto[0].master_key);
|
||||
call->audiostream_encrypted=TRUE;
|
||||
} else {
|
||||
ms_warning("Failed to find local crypto algo with tag: %d", stream->crypto_local_tag);
|
||||
call->audiostream_encrypted=FALSE;
|
||||
}
|
||||
}else call->audiostream_encrypted=FALSE;
|
||||
if (call->params.in_conference){
|
||||
/*transform the graph to connect it to the conference filter */
|
||||
|
|
@ -1929,7 +1934,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
|
||||
params.zid_file=lc->zrtp_secrets_cache;
|
||||
audio_stream_enable_zrtp(call->audiostream,¶ms);
|
||||
}else if (call->params.media_encryption==LinphoneMediaEncryptionSRTP){
|
||||
}else{
|
||||
call->current_params.media_encryption=linphone_call_are_all_streams_encrypted(call) ?
|
||||
LinphoneMediaEncryptionSRTP : LinphoneMediaEncryptionNone;
|
||||
}
|
||||
|
|
@ -2247,6 +2252,111 @@ const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) {
|
|||
return stats;
|
||||
}
|
||||
|
||||
float linphone_call_stats_update_sender_loss_rate(const LinphoneCallStats *stats) {
|
||||
const report_block_t *srb = NULL;
|
||||
|
||||
if (!stats || !stats->sent_rtcp)
|
||||
return 0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->sent_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->sent_rtcp, -1);
|
||||
if (rtcp_is_SR(stats->sent_rtcp))
|
||||
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
|
||||
else if (rtcp_is_RR(stats->sent_rtcp))
|
||||
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
|
||||
if (!srb)
|
||||
return 0.0;
|
||||
return 100.0 * report_block_get_fraction_lost(srb) / 256.0;
|
||||
}
|
||||
|
||||
float linphone_call_stats_update_receiver_loss_rate(const LinphoneCallStats *stats) {
|
||||
const report_block_t *rrb = NULL;
|
||||
|
||||
if (!stats || !stats->received_rtcp)
|
||||
return 0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->received_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->received_rtcp, -1);
|
||||
if (rtcp_is_RR(stats->received_rtcp))
|
||||
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
|
||||
else if (rtcp_is_SR(stats->received_rtcp))
|
||||
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
|
||||
if (!rrb)
|
||||
return 0.0;
|
||||
return 100.0 * report_block_get_fraction_lost(rrb) / 256.0;
|
||||
}
|
||||
|
||||
float linphone_call_stats_update_sender_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call) {
|
||||
const LinphoneCallParams *params;
|
||||
const PayloadType *pt;
|
||||
const report_block_t *srb = NULL;
|
||||
|
||||
if (!stats || !call || !stats->sent_rtcp)
|
||||
return 0.0;
|
||||
params = linphone_call_get_current_params(call);
|
||||
if (!params)
|
||||
return 0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->sent_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->sent_rtcp, -1);
|
||||
if (rtcp_is_SR(stats->sent_rtcp))
|
||||
srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0);
|
||||
else if (rtcp_is_RR(stats->sent_rtcp))
|
||||
srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0);
|
||||
if (!srb)
|
||||
return 0.0;
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
pt = linphone_call_params_get_used_audio_codec(params);
|
||||
else
|
||||
pt = linphone_call_params_get_used_video_codec(params);
|
||||
if (!pt || (pt->clock_rate == 0))
|
||||
return 0.0;
|
||||
return (float)report_block_get_interarrival_jitter(srb) / (float)pt->clock_rate;
|
||||
}
|
||||
|
||||
float linphone_call_stats_update_receiver_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call) {
|
||||
const LinphoneCallParams *params;
|
||||
const PayloadType *pt;
|
||||
const report_block_t *rrb = NULL;
|
||||
|
||||
if (!stats || !call || !stats->received_rtcp)
|
||||
return 0.0;
|
||||
params = linphone_call_get_current_params(call);
|
||||
if (!params)
|
||||
return 0.0;
|
||||
/* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */
|
||||
if (stats->received_rtcp->b_cont != NULL)
|
||||
msgpullup(stats->received_rtcp, -1);
|
||||
if (rtcp_is_SR(stats->received_rtcp))
|
||||
rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0);
|
||||
else if (rtcp_is_RR(stats->received_rtcp))
|
||||
rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0);
|
||||
if (!rrb)
|
||||
return 0.0;
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
pt = linphone_call_params_get_used_audio_codec(params);
|
||||
else
|
||||
pt = linphone_call_params_get_used_video_codec(params);
|
||||
if (!pt || (pt->clock_rate == 0))
|
||||
return 0.0;
|
||||
return (float)report_block_get_interarrival_jitter(rrb) / (float)pt->clock_rate;
|
||||
}
|
||||
|
||||
uint64_t linphone_call_stats_update_late_packets_cumulative_number(const LinphoneCallStats *stats, LinphoneCall *call) {
|
||||
rtp_stats_t rtp_stats;
|
||||
|
||||
if (!stats || !call)
|
||||
return 0;
|
||||
memset(&rtp_stats, 0, sizeof(rtp_stats));
|
||||
if (stats->type == LINPHONE_CALL_STATS_AUDIO)
|
||||
audio_stream_get_local_rtp_stats(call->audiostream, &rtp_stats);
|
||||
#ifdef VIDEO_ENABLED
|
||||
else
|
||||
video_stream_get_local_rtp_stats(call->videostream, &rtp_stats);
|
||||
#endif
|
||||
return rtp_stats.outoftime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable recording of the call (voice-only).
|
||||
* This function must be used before the call parameters are assigned to the call.
|
||||
|
|
@ -2572,7 +2682,6 @@ bool_t linphone_call_is_in_conference(const LinphoneCall *call) {
|
|||
return call->params.in_conference;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform a zoom of the video displayed during a call.
|
||||
* @param call the call.
|
||||
|
|
@ -2608,28 +2717,16 @@ void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx,
|
|||
}else ms_warning("Could not apply zoom: video output wasn't activated.");
|
||||
}
|
||||
|
||||
#ifndef USE_BELLESIP
|
||||
static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphoneProxyConfig *dest_proxy){
|
||||
#else
|
||||
static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphoneProxyConfig *dest_proxy){
|
||||
#endif
|
||||
LinphoneAddress *ctt=NULL;
|
||||
#ifdef USE_BELLESIP
|
||||
LinphoneAddress *ret=NULL;
|
||||
#else
|
||||
char* ret;
|
||||
#endif
|
||||
const char *localip=call->localip;
|
||||
|
||||
/* first use user's supplied ip address if asked*/
|
||||
if (linphone_core_get_firewall_policy(lc)==LinphonePolicyUseNatAddress){
|
||||
ctt=linphone_core_get_primary_contact_parsed(lc);
|
||||
linphone_address_set_domain(ctt,linphone_core_get_nat_address_resolved(lc));
|
||||
#ifdef USE_BELLESIP
|
||||
ret=ctt;
|
||||
#else
|
||||
ret=linphone_address_as_string(ctt);
|
||||
#endif
|
||||
} else if (call->op && sal_op_get_contact(call->op)!=NULL){
|
||||
/* if already choosed, don't change it */
|
||||
return NULL;
|
||||
|
|
@ -2637,19 +2734,11 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call ,
|
|||
/* if the ping OPTIONS request succeeded use the contact guessed from the
|
||||
received, rport*/
|
||||
ms_message("Contact has been fixed using OPTIONS"/* to %s",guessed*/);
|
||||
#ifdef USE_BELLESIP
|
||||
ret=linphone_address_clone(sal_op_get_contact(call->ping_op));;
|
||||
#else
|
||||
ret=ms_strdup(sal_op_get_contact(call->ping_op));
|
||||
#endif
|
||||
} else if (dest_proxy && dest_proxy->op && sal_op_get_contact(dest_proxy->op)){
|
||||
/*if using a proxy, use the contact address as guessed with the REGISTERs*/
|
||||
ms_message("Contact has been fixed using proxy" /*to %s",fixed_contact*/);
|
||||
#ifdef USE_BELLESIP
|
||||
ret=linphone_address_clone(sal_op_get_contact(dest_proxy->op));
|
||||
#else
|
||||
ret=ms_strdup(sal_op_get_contact(dest_proxy->op));
|
||||
#endif
|
||||
} else {
|
||||
ctt=linphone_core_get_primary_contact_parsed(lc);
|
||||
if (ctt!=NULL){
|
||||
|
|
@ -2657,16 +2746,9 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call ,
|
|||
linphone_address_set_domain(ctt,localip);
|
||||
linphone_address_set_port(ctt,linphone_core_get_sip_port(lc));
|
||||
ms_message("Contact has been fixed using local ip"/* to %s",ret*/);
|
||||
#ifdef USE_BELLESIP
|
||||
ret=ctt;
|
||||
#else
|
||||
ret=linphone_address_as_string_uri_only(ctt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef USE_BELLESIP
|
||||
if (ctt) linphone_address_destroy(ctt);
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
|
||||
|
|
@ -2688,4 +2770,4 @@ void linphone_call_set_contact_op(LinphoneCall* call) {
|
|||
sal_op_set_contact(call->op, contact);
|
||||
linphone_address_destroy(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2873,17 +2873,21 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md){
|
||||
if (linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP){
|
||||
int i;
|
||||
for(i=0;i<md->n_active_streams;i++){
|
||||
SalStreamDescription *sd=&md->streams[i];
|
||||
if (sd->proto!=SalProtoRtpSavp){
|
||||
return TRUE;
|
||||
}
|
||||
bool_t linphone_core_media_description_has_srtp(const SalMediaDescription *md){
|
||||
int i;
|
||||
if (md->n_active_streams==0) return FALSE;
|
||||
|
||||
for(i=0;i<md->n_active_streams;i++){
|
||||
const SalStreamDescription *sd=&md->streams[i];
|
||||
if (sd->proto!=SalProtoRtpSavp){
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md){
|
||||
return linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP && !linphone_core_media_description_has_srtp(md);
|
||||
}
|
||||
|
||||
void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
|
||||
|
|
@ -2899,7 +2903,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
md=sal_call_get_final_media_description(call->op);
|
||||
if (md){
|
||||
if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){
|
||||
sal_call_decline(call->op,SalReasonMedia,NULL);
|
||||
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
|
||||
linphone_call_stop_media_streams(call);
|
||||
linphone_core_del_call(lc,call);
|
||||
linphone_call_unref(call);
|
||||
|
|
@ -3325,6 +3329,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
|
|||
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
|
||||
new_md=sal_call_get_final_media_description(call->op);
|
||||
linphone_core_update_streams(lc, call, new_md);
|
||||
linphone_call_fix_call_parameters(call);
|
||||
if (new_md){
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}else call->media_pending=TRUE;
|
||||
|
|
@ -6267,7 +6272,7 @@ void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp){
|
|||
*
|
||||
**/
|
||||
int linphone_core_get_video_dscp(const LinphoneCore *lc){
|
||||
return lp_config_get_int(lc->config,"rtp","video_dscp",0x2e);
|
||||
return lp_config_get_int(lc->config,"rtp","video_dscp",0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "ortp/payloadtype.h"
|
||||
#include "mediastreamer2/mscommon.h"
|
||||
#include "mediastreamer2/msvideo.h"
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "sipsetup.h"
|
||||
|
|
@ -32,9 +33,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "lpconfig.h"
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include <belle-sip/dict.h>
|
||||
|
||||
#define LINPHONE_IPADDR_SIZE 64
|
||||
#define LINPHONE_HOSTNAME_SIZE 128
|
||||
|
||||
|
|
@ -94,6 +92,7 @@ typedef struct _LCSipTransports{
|
|||
|
||||
/**
|
||||
* Enum describing transport type for LinphoneAddress.
|
||||
* @ingroup linphone_address
|
||||
**/
|
||||
enum _LinphoneTransportType{
|
||||
LinphoneTransportUdp,
|
||||
|
|
@ -103,6 +102,10 @@ enum _LinphoneTransportType{
|
|||
};
|
||||
/*this enum MUST be kept in sync with the SalTransport from sal.h*/
|
||||
|
||||
/**
|
||||
* Typedef for transport type enum.
|
||||
* @ingroup linphone_address
|
||||
**/
|
||||
typedef enum _LinphoneTransportType LinphoneTransportType;
|
||||
|
||||
/**
|
||||
|
|
@ -166,7 +169,7 @@ enum _LinphoneReason{
|
|||
LinphoneReasonNotFound, /**<Destination of the calls was not found.*/
|
||||
LinphoneReasonNotAnswered, /**<The call was not answered in time*/
|
||||
LinphoneReasonBusy, /**<Phone line was busy */
|
||||
LinphoneReasonMedia, /**<Incompatible media */
|
||||
LinphoneReasonUnsupportedContent, /**<Unsupported content */
|
||||
LinphoneReasonIOError, /**<Transport error: connection failures, disconnections etc...*/
|
||||
LinphoneReasonDoNotDisturb, /**<Do not disturb reason*/
|
||||
LinphoneReasonUnauthorized, /**<Operation is unauthorized because missing credential*/
|
||||
|
|
@ -174,6 +177,9 @@ enum _LinphoneReason{
|
|||
LinphoneReasonNoMatch /**<Operation could not be executed by server or remote client because it didn't have any context for it*/
|
||||
};
|
||||
|
||||
/*for compatibility*/
|
||||
#define LinphoneReasonMedia LinphoneReasonUnsupportedContent
|
||||
|
||||
/**
|
||||
* Enum describing failure reasons.
|
||||
* @ingroup misc
|
||||
|
|
@ -579,7 +585,11 @@ struct _LinphoneCallStats {
|
|||
|
||||
LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call);
|
||||
LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call);
|
||||
|
||||
LINPHONE_PUBLIC float linphone_call_stats_update_sender_loss_rate(const LinphoneCallStats *stats);
|
||||
LINPHONE_PUBLIC float linphone_call_stats_update_receiver_loss_rate(const LinphoneCallStats *stats);
|
||||
LINPHONE_PUBLIC float linphone_call_stats_update_sender_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call);
|
||||
LINPHONE_PUBLIC float linphone_call_stats_update_receiver_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call);
|
||||
LINPHONE_PUBLIC uint64_t linphone_call_stats_update_late_packets_cumulative_number(const LinphoneCallStats *stats, LinphoneCall *call);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void (*LinphoneCallCbFunc)(LinphoneCall *call,void * user_data);
|
||||
|
|
@ -652,6 +662,7 @@ LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall
|
|||
LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy);
|
||||
LINPHONE_PUBLIC void linphone_call_start_recording(LinphoneCall *call);
|
||||
LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Return TRUE if this call is currently part of a conference
|
||||
* @param call #LinphoneCall
|
||||
|
|
@ -977,6 +988,20 @@ LINPHONE_PUBLIC MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int
|
|||
LINPHONE_PUBLIC void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Notify the destination of the chat message being composed that the user is typing a new message.
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which a new message is being typed.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_compose(LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Tells whether the remote is currently composing a message.
|
||||
* @param[in] cr The "LinphoneChatRoom object corresponding to the conversation.
|
||||
* @return TRUE if the remote is currently composing a message, FALSE otherwise.
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr);
|
||||
|
||||
LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud);
|
||||
|
|
@ -1130,6 +1155,14 @@ typedef void (*LinphoneCoreTextMessageReceivedCb)(LinphoneCore *lc, LinphoneChat
|
|||
*/
|
||||
typedef void (*LinphoneCoreMessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
|
||||
|
||||
/**
|
||||
* Is composing notification callback prototype.
|
||||
*
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @param[in] room #LinphoneChatRoom involved in the conversation.
|
||||
*/
|
||||
typedef void (*LinphoneCoreIsComposingReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room);
|
||||
|
||||
/**
|
||||
* Callback for being notified of DTMFs received.
|
||||
* @param lc the linphone core
|
||||
|
|
@ -1179,6 +1212,7 @@ typedef struct _LinphoneCoreVTable{
|
|||
LinphoneCoreAuthInfoRequestedCb auth_info_requested; /**< Ask the application some authentication information */
|
||||
LinphoneCoreCallLogUpdatedCb call_log_updated; /**< Notifies that call log list has been updated */
|
||||
LinphoneCoreMessageReceivedCb message_received; /** a message is received, can be text or external body*/
|
||||
LinphoneCoreIsComposingReceivedCb is_composing_received; /**< An is-composing notification has been received */
|
||||
LinphoneCoreDtmfReceivedCb dtmf_received; /**< A dtmf has been received received */
|
||||
LinphoneCoreReferReceivedCb refer_received; /**< An out of call refer was received */
|
||||
LinphoneCoreCallEncryptionChangedCb call_encryption_changed; /**<Notifies on change in the encryption of call streams */
|
||||
|
|
@ -2202,18 +2236,6 @@ LINPHONE_PUBLIC int linphone_core_get_video_dscp(const LinphoneCore *lc);
|
|||
LINPHONE_PUBLIC const char *linphone_core_get_video_display_filter(LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC void linphone_core_set_video_display_filter(LinphoneCore *lc, const char *filtername);
|
||||
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
*/
|
||||
|
||||
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch)
|
||||
BELLE_SIP_DECLARE_TYPES_END
|
||||
|
||||
|
||||
/** Contact Providers
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ public:
|
|||
vTable.call_encryption_changed = callEncryptionChange;
|
||||
vTable.text_received = text_received;
|
||||
vTable.message_received = message_received;
|
||||
vTable.is_composing_received = is_composing_received;
|
||||
vTable.dtmf_received = dtmf_received;
|
||||
vTable.new_subscription_requested = new_subscription_requested;
|
||||
vTable.notify_presence_received = notify_presence_received;
|
||||
|
|
@ -225,6 +226,7 @@ public:
|
|||
/*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/
|
||||
textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V");
|
||||
messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V");
|
||||
isComposingReceivedId = env->GetMethodID(listenerClass,"isComposingReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;)V");
|
||||
dtmfReceivedId = env->GetMethodID(listenerClass,"dtmfReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;I)V");
|
||||
infoReceivedId = env->GetMethodID(listenerClass,"infoReceived",
|
||||
"(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneInfoMessage;)V");
|
||||
|
|
@ -307,6 +309,7 @@ public:
|
|||
jmethodID notifyPresenceReceivedId;
|
||||
jmethodID textReceivedId;
|
||||
jmethodID messageReceivedId;
|
||||
jmethodID isComposingReceivedId;
|
||||
jmethodID dtmfReceivedId;
|
||||
jmethodID callStatsUpdatedId;
|
||||
jmethodID transferStateId;
|
||||
|
|
@ -550,6 +553,19 @@ public:
|
|||
,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room)
|
||||
,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg));
|
||||
}
|
||||
static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->isComposingReceivedId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room));
|
||||
}
|
||||
static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
|
|
@ -2311,6 +2327,12 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_deleteHistory(JNIEnv
|
|||
,jlong ptr) {
|
||||
linphone_chat_room_delete_history((LinphoneChatRoom*)ptr);
|
||||
}
|
||||
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneChatRoomImpl_compose(JNIEnv *env, jobject thiz, jlong ptr) {
|
||||
linphone_chat_room_compose((LinphoneChatRoom *)ptr);
|
||||
}
|
||||
JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneChatRoomImpl_isRemoteComposing(JNIEnv *env, jobject thiz, jlong ptr) {
|
||||
return (jboolean)linphone_chat_room_is_remote_composing((LinphoneChatRoom *)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_deleteMessage(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong room
|
||||
|
|
|
|||
|
|
@ -1239,16 +1239,16 @@ SalReason linphone_reason_to_sal(LinphoneReason reason){
|
|||
return SalReasonTemporarilyUnavailable;
|
||||
case LinphoneReasonBusy:
|
||||
return SalReasonBusy;
|
||||
case LinphoneReasonMedia:
|
||||
return SalReasonMedia;
|
||||
case LinphoneReasonNotAcceptable:
|
||||
return SalReasonNotAcceptable;
|
||||
case LinphoneReasonIOError:
|
||||
return SalReasonServiceUnavailable;
|
||||
case LinphoneReasonDoNotDisturb:
|
||||
return SalReasonDoNotDisturb;
|
||||
case LinphoneReasonUnauthorized:
|
||||
return SalReasonUnauthorized;
|
||||
case LinphoneReasonNotAcceptable:
|
||||
return SalReasonNotAcceptable;
|
||||
case LinphoneReasonUnsupportedContent:
|
||||
return SalReasonUnsupportedContent;
|
||||
case LinphoneReasonNoMatch:
|
||||
return SalReasonNoMatch;
|
||||
}
|
||||
|
|
@ -1273,8 +1273,8 @@ LinphoneReason linphone_reason_from_sal(SalReason r){
|
|||
case SalReasonForbidden:
|
||||
ret=LinphoneReasonBadCredentials;
|
||||
break;
|
||||
case SalReasonMedia:
|
||||
ret=LinphoneReasonMedia;
|
||||
case SalReasonNotAcceptable:
|
||||
ret=LinphoneReasonNotAcceptable;
|
||||
break;
|
||||
case SalReasonNotFound:
|
||||
ret=LinphoneReasonNotFound;
|
||||
|
|
@ -1294,8 +1294,8 @@ LinphoneReason linphone_reason_from_sal(SalReason r){
|
|||
case SalReasonUnauthorized:
|
||||
ret=LinphoneReasonUnauthorized;
|
||||
break;
|
||||
case SalReasonNotAcceptable:
|
||||
ret=LinphoneReasonNotAcceptable;
|
||||
case SalReasonUnsupportedContent:
|
||||
ret=LinphoneReasonUnsupportedContent;
|
||||
break;
|
||||
case SalReasonNoMatch:
|
||||
ret=LinphoneReasonNoMatch;
|
||||
|
|
|
|||
|
|
@ -22,15 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "lpconfig.h"
|
||||
#include "linphonepresence.h"
|
||||
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/xpathInternals.h>
|
||||
|
||||
|
||||
#define XMLPARSING_BUFFER_LEN 2048
|
||||
#define MAX_XPATH_LENGTH 256
|
||||
|
||||
|
||||
|
||||
extern const char *__policy_enum_to_str(LinphoneSubscribePolicy pol);
|
||||
|
|
@ -83,13 +74,6 @@ struct _LinphonePresenceModel {
|
|||
MSList *notes; /**< A list of _LinphonePresenceNote structures. */
|
||||
};
|
||||
|
||||
typedef struct _xmlparsing_context {
|
||||
xmlDoc *doc;
|
||||
xmlXPathContextPtr xpath_ctx;
|
||||
char errorBuffer[XMLPARSING_BUFFER_LEN];
|
||||
char warningBuffer[XMLPARSING_BUFFER_LEN];
|
||||
} xmlparsing_context_t;
|
||||
|
||||
|
||||
static const char *person_prefix = "/pidf:presence/dm:person";
|
||||
|
||||
|
|
@ -98,38 +82,6 @@ static const char *person_prefix = "/pidf:presence/dm:person";
|
|||
* PRIVATE FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
||||
static xmlparsing_context_t * xmlparsing_context_new() {
|
||||
xmlparsing_context_t *xmlCtx = (xmlparsing_context_t *)malloc(sizeof(xmlparsing_context_t));
|
||||
if (xmlCtx != NULL) {
|
||||
xmlCtx->doc = NULL;
|
||||
xmlCtx->xpath_ctx = NULL;
|
||||
xmlCtx->errorBuffer[0] = '\0';
|
||||
xmlCtx->warningBuffer[0] = '\0';
|
||||
}
|
||||
return xmlCtx;
|
||||
}
|
||||
|
||||
static void xmlparsing_context_destroy(xmlparsing_context_t *ctx) {
|
||||
if (ctx->doc != NULL) {
|
||||
xmlFreeDoc(ctx->doc);
|
||||
ctx->doc = NULL;
|
||||
}
|
||||
if (ctx->xpath_ctx != NULL) {
|
||||
xmlXPathFreeContext(ctx->xpath_ctx);
|
||||
ctx->xpath_ctx = NULL;
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void xmlparsing_genericxml_error(void *ctx, const char *fmt, ...) {
|
||||
xmlparsing_context_t *xmlCtx = (xmlparsing_context_t *)ctx;
|
||||
int sl = strlen(xmlCtx->errorBuffer);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(xmlCtx->errorBuffer + sl, XMLPARSING_BUFFER_LEN - sl, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static char presence_id_valid_characters[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
static char * generate_presence_id(void) {
|
||||
|
|
@ -1183,45 +1135,6 @@ void * linphone_presence_note_get_user_data(LinphonePresenceNote *note) {
|
|||
* XML PRESENCE INTERNAL HANDLING *
|
||||
****************************************************************************/
|
||||
|
||||
static int create_xml_xpath_context(xmlparsing_context_t *xml_ctx) {
|
||||
if (xml_ctx->xpath_ctx != NULL) {
|
||||
xmlXPathFreeContext(xml_ctx->xpath_ctx);
|
||||
}
|
||||
xml_ctx->xpath_ctx = xmlXPathNewContext(xml_ctx->doc);
|
||||
if (xml_ctx->xpath_ctx == NULL) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char * get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression) {
|
||||
xmlXPathObjectPtr xpath_obj;
|
||||
xmlChar *text = NULL;
|
||||
int i;
|
||||
|
||||
xpath_obj = xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx);
|
||||
if (xpath_obj != NULL) {
|
||||
if (xpath_obj->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = xpath_obj->nodesetval;
|
||||
for (i = 0; i < nodes->nodeNr; i++) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
if (node->children != NULL) {
|
||||
text = xmlNodeListGetString(xml_ctx->doc, node->children, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
}
|
||||
|
||||
return (char *)text;
|
||||
}
|
||||
|
||||
static void free_xml_text_content(const char *text) {
|
||||
xmlFree((xmlChar *)text);
|
||||
}
|
||||
|
||||
static xmlXPathObjectPtr get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression) {
|
||||
return xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx);
|
||||
}
|
||||
|
||||
static const char *service_prefix = "/pidf:presence/pidf:tuple";
|
||||
|
||||
static int process_pidf_xml_presence_service_notes(xmlparsing_context_t *xml_ctx, LinphonePresenceService *service, unsigned int service_idx) {
|
||||
|
|
@ -1233,19 +1146,19 @@ static int process_pidf_xml_presence_service_notes(xmlparsing_context_t *xml_ctx
|
|||
int i;
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:note", service_prefix, service_idx);
|
||||
note_object = get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
note_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
if ((note_object != NULL) && (note_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= note_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:note[%i]", service_prefix, service_idx, i);
|
||||
note_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
note_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (note_str == NULL) continue;
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:note[%i]/@xml:lang", service_prefix, service_idx, i);
|
||||
lang = get_xml_text_content(xml_ctx, xpath_str);
|
||||
lang = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
||||
note = linphone_presence_note_new(note_str, lang);
|
||||
presence_service_add_note(service, note);
|
||||
if (lang != NULL) free_xml_text_content(lang);
|
||||
free_xml_text_content(note_str);
|
||||
if (lang != NULL) linphone_free_xml_text_content(lang);
|
||||
linphone_free_xml_text_content(note_str);
|
||||
}
|
||||
}
|
||||
if (note_object != NULL) xmlXPathFreeObject(note_object);
|
||||
|
|
@ -1264,11 +1177,11 @@ static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, Lin
|
|||
LinphonePresenceBasicStatus basic_status;
|
||||
int i;
|
||||
|
||||
service_object = get_xml_xpath_object_for_node_list(xml_ctx, service_prefix);
|
||||
service_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, service_prefix);
|
||||
if ((service_object != NULL) && (service_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= service_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:status/pidf:basic", service_prefix, i);
|
||||
basic_status_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
basic_status_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (basic_status_str == NULL)
|
||||
continue;
|
||||
|
||||
|
|
@ -1278,33 +1191,33 @@ static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, Lin
|
|||
basic_status = LinphonePresenceBasicStatusClosed;
|
||||
} else {
|
||||
/* Invalid value for basic status. */
|
||||
free_xml_text_content(basic_status_str);
|
||||
linphone_free_xml_text_content(basic_status_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:timestamp", service_prefix, i);
|
||||
timestamp_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
timestamp_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:contact", service_prefix, i);
|
||||
contact_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
contact_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/@id", service_prefix, i);
|
||||
service_id_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
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));
|
||||
free_xml_text_content(timestamp_str);
|
||||
linphone_free_xml_text_content(timestamp_str);
|
||||
}
|
||||
if (contact_str != NULL) {
|
||||
linphone_presence_service_set_contact(service, contact_str);
|
||||
free_xml_text_content(contact_str);
|
||||
linphone_free_xml_text_content(contact_str);
|
||||
}
|
||||
process_pidf_xml_presence_service_notes(xml_ctx, service, i);
|
||||
linphone_presence_model_add_service(model, service);
|
||||
}
|
||||
free_xml_text_content(basic_status_str);
|
||||
if (service_id_str != NULL) free_xml_text_content(service_id_str);
|
||||
linphone_free_xml_text_content(basic_status_str);
|
||||
if (service_id_str != NULL) linphone_free_xml_text_content(service_id_str);
|
||||
}
|
||||
}
|
||||
if (service_object != NULL) xmlXPathFreeObject(service_object);
|
||||
|
|
@ -1333,11 +1246,11 @@ static int process_pidf_xml_presence_person_activities(xmlparsing_context_t *xml
|
|||
int err = 0;
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/rpid:activities", person_prefix, person_idx);
|
||||
activities_nodes_object = get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
activities_nodes_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
if ((activities_nodes_object != NULL) && (activities_nodes_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= activities_nodes_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/rpid:activities[%i]/rpid:*", person_prefix, person_idx, i);
|
||||
activities_object = get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
activities_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
if ((activities_object != NULL) && (activities_object->nodesetval != NULL)) {
|
||||
for (j = 0; j < activities_object->nodesetval->nodeNr; j++) {
|
||||
activity_node = activities_object->nodesetval->nodeTab[j];
|
||||
|
|
@ -1345,14 +1258,14 @@ static int process_pidf_xml_presence_person_activities(xmlparsing_context_t *xml
|
|||
LinphonePresenceActivityType acttype;
|
||||
description = (const char *)xmlNodeGetContent(activity_node);
|
||||
if ((description != NULL) && (description[0] == '\0')) {
|
||||
free_xml_text_content(description);
|
||||
linphone_free_xml_text_content(description);
|
||||
description = NULL;
|
||||
}
|
||||
err = activity_name_to_presence_activity_type((const char *)activity_node->name, &acttype);
|
||||
if (err < 0) break;
|
||||
activity = linphone_presence_activity_new(acttype, description);
|
||||
linphone_presence_person_add_activity(person, activity);
|
||||
if (description != NULL) free_xml_text_content(description);
|
||||
if (description != NULL) linphone_free_xml_text_content(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1374,37 +1287,37 @@ static int process_pidf_xml_presence_person_notes(xmlparsing_context_t *xml_ctx,
|
|||
int i;
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/rpid:activities/rpid:note", person_prefix, person_idx);
|
||||
note_object = get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
note_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
if ((note_object != NULL) && (note_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= note_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/rpid:activities/rpid:note[%i]", person_prefix, person_idx, i);
|
||||
note_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
note_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (note_str == NULL) continue;
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/rpid:activities/rpid:note[%i]/@xml:lang", person_prefix, person_idx, i);
|
||||
lang = get_xml_text_content(xml_ctx, xpath_str);
|
||||
lang = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
||||
note = linphone_presence_note_new(note_str, lang);
|
||||
presence_person_add_activities_note(person, note);
|
||||
if (lang != NULL) free_xml_text_content(lang);
|
||||
free_xml_text_content(note_str);
|
||||
if (lang != NULL) linphone_free_xml_text_content(lang);
|
||||
linphone_free_xml_text_content(note_str);
|
||||
}
|
||||
}
|
||||
if (note_object != NULL) xmlXPathFreeObject(note_object);
|
||||
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/dm:note", person_prefix, person_idx);
|
||||
note_object = get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
note_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
|
||||
if ((note_object != NULL) && (note_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= note_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/dm:note[%i]", person_prefix, person_idx, i);
|
||||
note_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
note_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (note_str == NULL) continue;
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/dm:note[%i]/@xml:lang", person_prefix, person_idx, i);
|
||||
lang = get_xml_text_content(xml_ctx, xpath_str);
|
||||
lang = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
||||
note = linphone_presence_note_new(note_str, lang);
|
||||
presence_person_add_note(person, note);
|
||||
if (lang != NULL) free_xml_text_content(lang);
|
||||
free_xml_text_content(note_str);
|
||||
if (lang != NULL) linphone_free_xml_text_content(lang);
|
||||
linphone_free_xml_text_content(note_str);
|
||||
}
|
||||
}
|
||||
if (note_object != NULL) xmlXPathFreeObject(note_object);
|
||||
|
|
@ -1422,13 +1335,13 @@ static int process_pidf_xml_presence_persons(xmlparsing_context_t *xml_ctx, Linp
|
|||
int i;
|
||||
int err = 0;
|
||||
|
||||
person_object = get_xml_xpath_object_for_node_list(xml_ctx, person_prefix);
|
||||
person_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, person_prefix);
|
||||
if ((person_object != NULL) && (person_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= person_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/@id", person_prefix, i);
|
||||
person_id_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
person_id_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:timestamp", person_prefix, i);
|
||||
person_timestamp_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
person_timestamp_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (person_timestamp_str == NULL)
|
||||
timestamp = time(NULL);
|
||||
else
|
||||
|
|
@ -1446,8 +1359,8 @@ static int process_pidf_xml_presence_persons(xmlparsing_context_t *xml_ctx, Linp
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (person_id_str != NULL) free_xml_text_content(person_id_str);
|
||||
if (person_timestamp_str != NULL) free_xml_text_content(person_timestamp_str);
|
||||
if (person_id_str != NULL) linphone_free_xml_text_content(person_id_str);
|
||||
if (person_timestamp_str != NULL) linphone_free_xml_text_content(person_timestamp_str);
|
||||
}
|
||||
}
|
||||
if (person_object != NULL) xmlXPathFreeObject(person_object);
|
||||
|
|
@ -1467,19 +1380,19 @@ static int process_pidf_xml_presence_notes(xmlparsing_context_t *xml_ctx, Linpho
|
|||
const char *lang;
|
||||
int i;
|
||||
|
||||
note_object = get_xml_xpath_object_for_node_list(xml_ctx, "/pidf:presence/pidf:note");
|
||||
note_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/pidf:presence/pidf:note");
|
||||
if ((note_object != NULL) && (note_object->nodesetval != NULL)) {
|
||||
for (i = 1; i <= note_object->nodesetval->nodeNr; i++) {
|
||||
snprintf(xpath_str, sizeof(xpath_str), "/pidf:presence/pidf:note[%i]", i);
|
||||
note_str = get_xml_text_content(xml_ctx, xpath_str);
|
||||
note_str = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (note_str == NULL) continue;
|
||||
snprintf(xpath_str, sizeof(xpath_str), "/pidf:presence/pidf:note[%i]/@xml:lang", i);
|
||||
lang = get_xml_text_content(xml_ctx, xpath_str);
|
||||
lang = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
||||
note = linphone_presence_note_new(note_str, lang);
|
||||
presence_model_add_note(model, note);
|
||||
if (lang != NULL) free_xml_text_content(lang);
|
||||
free_xml_text_content(note_str);
|
||||
if (lang != NULL) linphone_free_xml_text_content(lang);
|
||||
linphone_free_xml_text_content(note_str);
|
||||
}
|
||||
}
|
||||
if (note_object != NULL) xmlXPathFreeObject(note_object);
|
||||
|
|
@ -1491,7 +1404,7 @@ static LinphonePresenceModel * process_pidf_xml_presence_notification(xmlparsing
|
|||
LinphonePresenceModel *model = NULL;
|
||||
int err;
|
||||
|
||||
if (create_xml_xpath_context(xml_ctx) < 0)
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0)
|
||||
return NULL;
|
||||
|
||||
model = linphone_presence_model_new();
|
||||
|
|
@ -1606,15 +1519,15 @@ void linphone_notify_parse_presence(SalOp *op, const char *content_type, const c
|
|||
}
|
||||
|
||||
if (strcmp(content_subtype, "pidf+xml") == 0) {
|
||||
xml_ctx = xmlparsing_context_new();
|
||||
xmlSetGenericErrorFunc(xml_ctx, xmlparsing_genericxml_error);
|
||||
xml_ctx = linphone_xmlparsing_context_new();
|
||||
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
|
||||
xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0);
|
||||
if (xml_ctx->doc != NULL) {
|
||||
model = process_pidf_xml_presence_notification(xml_ctx);
|
||||
} else {
|
||||
ms_warning("Wrongly formatted presence XML: %s", xml_ctx->errorBuffer);
|
||||
}
|
||||
xmlparsing_context_destroy(xml_ctx);
|
||||
linphone_xmlparsing_context_destroy(xml_ctx);
|
||||
} else {
|
||||
ms_error("Unknown content type '%s/%s' for presence", content_type, content_subtype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ extern "C" {
|
|||
#include "sal/sal.h"
|
||||
#include "sipsetup.h"
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include <belle-sip/dict.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
|
@ -201,22 +204,22 @@ struct _LinphoneCall
|
|||
LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/
|
||||
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
|
||||
int localdesc_changed;
|
||||
|
||||
|
||||
bool_t refer_pending;
|
||||
bool_t media_pending;
|
||||
bool_t audio_muted;
|
||||
bool_t camera_enabled;
|
||||
|
||||
|
||||
bool_t all_muted; /*this flag is set during early medias*/
|
||||
bool_t playing_ringbacktone;
|
||||
bool_t owns_call_log;
|
||||
bool_t ringing_beep; /* whether this call is ringing through an already existent current call*/
|
||||
|
||||
|
||||
bool_t videostream_encrypted;
|
||||
bool_t audiostream_encrypted;
|
||||
bool_t auth_token_verified;
|
||||
bool_t defer_update;
|
||||
|
||||
|
||||
bool_t was_automatically_paused;
|
||||
bool_t ping_replied;
|
||||
bool_t record_active;
|
||||
|
|
@ -320,6 +323,7 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call);
|
|||
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);
|
||||
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
|
||||
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md);
|
||||
bool_t linphone_core_media_description_has_srtp(const SalMediaDescription *md);
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
|
||||
void linphone_core_write_friends_config(LinphoneCore* lc);
|
||||
|
|
@ -338,6 +342,7 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon
|
|||
int 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);
|
||||
|
||||
void linphone_core_play_tone(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -379,9 +384,9 @@ LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer);
|
|||
|
||||
static const int linphone_proxy_config_magic=0x7979;
|
||||
|
||||
/*chat*/
|
||||
/*chat*/
|
||||
void linphone_chat_message_destroy(LinphoneChatMessage* msg);
|
||||
/**/
|
||||
/**/
|
||||
|
||||
struct _LinphoneProxyConfig
|
||||
{
|
||||
|
|
@ -426,16 +431,26 @@ struct _LinphoneAuthInfo
|
|||
bool_t works;
|
||||
};
|
||||
|
||||
typedef enum _LinphoneIsComposingState {
|
||||
LinphoneIsComposingIdle,
|
||||
LinphoneIsComposingActive
|
||||
} LinphoneIsComposingState;
|
||||
|
||||
struct _LinphoneChatRoom{
|
||||
struct _LinphoneCore *lc;
|
||||
char *peer;
|
||||
LinphoneAddress *peer_url;
|
||||
void * user_data;
|
||||
MSList *messages_hist;
|
||||
LinphoneIsComposingState remote_is_composing;
|
||||
LinphoneIsComposingState is_composing;
|
||||
belle_sip_source_t *remote_composing_refresh_timer;
|
||||
belle_sip_source_t *composing_idle_timer;
|
||||
belle_sip_source_t *composing_refresh_timer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct _LinphoneFriend{
|
||||
LinphoneAddress *uri;
|
||||
SalOp *insub;
|
||||
|
|
@ -487,7 +502,7 @@ typedef struct rtp_config
|
|||
int nortp_timeout;
|
||||
int disable_upnp;
|
||||
bool_t rtp_no_xmit_on_audio_mute;
|
||||
/* stop rtp xmit when audio muted */
|
||||
/* stop rtp xmit when audio muted */
|
||||
bool_t audio_adaptive_jitt_comp_enabled;
|
||||
bool_t video_adaptive_jitt_comp_enabled;
|
||||
bool_t pad;
|
||||
|
|
@ -633,12 +648,12 @@ struct _LinphoneCore
|
|||
bool_t apply_nat_settings;
|
||||
bool_t initial_subscribes_sent;
|
||||
bool_t bl_refresh;
|
||||
|
||||
|
||||
bool_t preview_finished;
|
||||
bool_t auto_net_state_mon;
|
||||
bool_t network_reachable;
|
||||
bool_t use_preview_window;
|
||||
|
||||
|
||||
time_t network_last_check;
|
||||
bool_t network_last_status;
|
||||
|
||||
|
|
@ -788,6 +803,46 @@ LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatu
|
|||
const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* XML UTILITY FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/xpathInternals.h>
|
||||
|
||||
#define XMLPARSING_BUFFER_LEN 2048
|
||||
#define MAX_XPATH_LENGTH 256
|
||||
|
||||
typedef struct _xmlparsing_context {
|
||||
xmlDoc *doc;
|
||||
xmlXPathContextPtr xpath_ctx;
|
||||
char errorBuffer[XMLPARSING_BUFFER_LEN];
|
||||
char warningBuffer[XMLPARSING_BUFFER_LEN];
|
||||
} xmlparsing_context_t;
|
||||
|
||||
xmlparsing_context_t * linphone_xmlparsing_context_new(void);
|
||||
void linphone_xmlparsing_context_destroy(xmlparsing_context_t *ctx);
|
||||
void linphone_xmlparsing_genericxml_error(void *ctx, const char *fmt, ...);
|
||||
int linphone_create_xml_xpath_context(xmlparsing_context_t *xml_ctx);
|
||||
char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
void linphone_free_xml_text_content(const char *text);
|
||||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
*/
|
||||
|
||||
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
|
||||
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
|
||||
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch)
|
||||
BELLE_SIP_DECLARE_TYPES_END
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -530,7 +530,7 @@ const char* sal_reason_to_string(const SalReason reason) {
|
|||
case SalReasonTemporarilyUnavailable: return "SalReasonTemporarilyUnavailable";
|
||||
case SalReasonNotFound: return "SalReasonNotFound";
|
||||
case SalReasonDoNotDisturb: return "SalReasonDoNotDisturb";
|
||||
case SalReasonMedia: return "SalReasonMedia";
|
||||
case SalReasonUnsupportedContent: return "SalReasonUnsupportedContent";
|
||||
case SalReasonForbidden: return "SalReasonForbidden";
|
||||
case SalReasonUnknown: return "SalReasonUnknown";
|
||||
case SalReasonServiceUnavailable: return "SalReasonServiceUnavailable";
|
||||
|
|
|
|||
98
coreapi/xml.c
Normal file
98
coreapi/xml.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2010-2013 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/xpathInternals.h>
|
||||
|
||||
|
||||
xmlparsing_context_t * linphone_xmlparsing_context_new(void) {
|
||||
xmlparsing_context_t *xmlCtx = (xmlparsing_context_t *)malloc(sizeof(xmlparsing_context_t));
|
||||
if (xmlCtx != NULL) {
|
||||
xmlCtx->doc = NULL;
|
||||
xmlCtx->xpath_ctx = NULL;
|
||||
xmlCtx->errorBuffer[0] = '\0';
|
||||
xmlCtx->warningBuffer[0] = '\0';
|
||||
}
|
||||
return xmlCtx;
|
||||
}
|
||||
|
||||
void linphone_xmlparsing_context_destroy(xmlparsing_context_t *ctx) {
|
||||
if (ctx->doc != NULL) {
|
||||
xmlFreeDoc(ctx->doc);
|
||||
ctx->doc = NULL;
|
||||
}
|
||||
if (ctx->xpath_ctx != NULL) {
|
||||
xmlXPathFreeContext(ctx->xpath_ctx);
|
||||
ctx->xpath_ctx = NULL;
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void linphone_xmlparsing_genericxml_error(void *ctx, const char *fmt, ...) {
|
||||
xmlparsing_context_t *xmlCtx = (xmlparsing_context_t *)ctx;
|
||||
int sl = strlen(xmlCtx->errorBuffer);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(xmlCtx->errorBuffer + sl, XMLPARSING_BUFFER_LEN - sl, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
int linphone_create_xml_xpath_context(xmlparsing_context_t *xml_ctx) {
|
||||
if (xml_ctx->xpath_ctx != NULL) {
|
||||
xmlXPathFreeContext(xml_ctx->xpath_ctx);
|
||||
}
|
||||
xml_ctx->xpath_ctx = xmlXPathNewContext(xml_ctx->doc);
|
||||
if (xml_ctx->xpath_ctx == NULL) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression) {
|
||||
xmlXPathObjectPtr xpath_obj;
|
||||
xmlChar *text = NULL;
|
||||
int i;
|
||||
|
||||
xpath_obj = xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx);
|
||||
if (xpath_obj != NULL) {
|
||||
if (xpath_obj->nodesetval != NULL) {
|
||||
xmlNodeSetPtr nodes = xpath_obj->nodesetval;
|
||||
for (i = 0; i < nodes->nodeNr; i++) {
|
||||
xmlNodePtr node = nodes->nodeTab[i];
|
||||
if (node->children != NULL) {
|
||||
text = xmlNodeListGetString(xml_ctx->doc, node->children, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
}
|
||||
|
||||
return (char *)text;
|
||||
}
|
||||
|
||||
void linphone_free_xml_text_content(const char *text) {
|
||||
xmlFree((xmlChar *)text);
|
||||
}
|
||||
|
||||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression) {
|
||||
return xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx);
|
||||
}
|
||||
21
gtk/chat.c
21
gtk/chat.c
|
|
@ -279,6 +279,16 @@ static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageS
|
|||
update_chat_state_message(state,msg);
|
||||
}
|
||||
|
||||
void linphone_gtk_compose_text(void) {
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list");
|
||||
GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
|
||||
LinphoneChatRoom *cr=g_object_get_data(G_OBJECT(w),"cr");
|
||||
if (cr) {
|
||||
linphone_chat_room_compose(cr);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_send_text(){
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list");
|
||||
|
|
@ -293,7 +303,11 @@ void linphone_gtk_send_text(){
|
|||
linphone_chat_room_send_message2(cr,msg,on_chat_state_changed,NULL);
|
||||
linphone_gtk_push_text(w,linphone_chat_message_get_from(msg),
|
||||
TRUE,cr,msg,FALSE);
|
||||
|
||||
// Disconnect and reconnect the "changed" signal to prevent triggering it when clearing the text entry.
|
||||
g_signal_handlers_disconnect_by_func(G_OBJECT(entry),(GCallback)linphone_gtk_compose_text,NULL);
|
||||
gtk_entry_set_text(GTK_ENTRY(entry),"");
|
||||
g_signal_connect_swapped(G_OBJECT(entry),"changed",(GCallback)linphone_gtk_compose_text,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -410,6 +424,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
|
|||
g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,NULL);
|
||||
entry = linphone_gtk_get_widget(chat_view,"text_entry");
|
||||
g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,NULL);
|
||||
g_signal_connect_swapped(G_OBJECT(entry),"changed",(GCallback)linphone_gtk_compose_text,NULL);
|
||||
g_signal_connect(G_OBJECT(notebook),"switch_page",(GCallback)linphone_gtk_notebook_tab_select,NULL);
|
||||
ms_free(with_str);
|
||||
return chat_view;
|
||||
|
|
@ -417,7 +432,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
|
|||
|
||||
LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with){
|
||||
char *tmp=linphone_address_as_string(with);
|
||||
LinphoneChatRoom *cr=linphone_core_create_chat_room(linphone_gtk_get_core(),tmp);
|
||||
LinphoneChatRoom *cr=linphone_core_get_or_create_chat_room(linphone_gtk_get_core(),tmp);
|
||||
ms_free(tmp);
|
||||
return cr;
|
||||
}
|
||||
|
|
@ -516,3 +531,7 @@ void linphone_gtk_text_received ( LinphoneCore *lc, LinphoneChatRoom *room,
|
|||
linphone_gtk_show_friends();
|
||||
|
||||
}
|
||||
|
||||
void linphone_gtk_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
|
||||
linphone_gtk_friend_list_update_chat_picture();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,18 @@ static GdkPixbuf *create_chat_picture(){
|
|||
return pixbuf;
|
||||
}
|
||||
|
||||
static GdkPixbuf *create_composing_unread_msg(){
|
||||
GdkPixbuf *pixbuf;
|
||||
pixbuf = create_pixbuf("composing_active_chat.png");
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static GdkPixbuf *create_composing_chat_picture(){
|
||||
GdkPixbuf *pixbuf;
|
||||
pixbuf = create_pixbuf("composing_chat.png");
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
void linphone_gtk_set_friend_status(GtkWidget *friendlist , LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){
|
||||
GtkTreeIter iter;
|
||||
|
|
@ -227,15 +239,23 @@ void linphone_gtk_friend_list_update_chat_picture(){
|
|||
GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
|
||||
GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist));
|
||||
LinphoneChatRoom *cr=NULL;
|
||||
bool_t is_composing;
|
||||
int nbmsg=0;
|
||||
if (gtk_tree_model_get_iter_first(model,&iter)) {
|
||||
do{
|
||||
gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1);
|
||||
nbmsg=linphone_chat_room_get_unread_messages_count(cr);
|
||||
is_composing=linphone_chat_room_is_remote_composing(cr);
|
||||
if(nbmsg != 0){
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_unread_msg(),-1);
|
||||
if (is_composing == TRUE)
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_composing_unread_msg(),-1);
|
||||
else
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_unread_msg(),-1);
|
||||
} else {
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_chat_picture(),-1);
|
||||
if (is_composing == TRUE)
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_composing_chat_picture(),-1);
|
||||
else
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_chat_picture(),-1);
|
||||
}
|
||||
}while(gtk_tree_model_iter_next(model,&iter));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.24"/>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="GtkWindow" id="ldap">
|
||||
<property name="can_focus">False</property>
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ void linphone_gtk_send_text();
|
|||
GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with);
|
||||
LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with);
|
||||
void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg);
|
||||
void linphone_gtk_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room);
|
||||
|
||||
void linphone_gtk_friend_list_update_chat_picture();
|
||||
void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la);
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
vtable.call_log_updated=linphone_gtk_call_log_updated;
|
||||
//vtable.text_received=linphone_gtk_text_received;
|
||||
vtable.message_received=linphone_gtk_text_received;
|
||||
vtable.is_composing_received=linphone_gtk_is_composing_received;
|
||||
vtable.refer_received=linphone_gtk_refer_received;
|
||||
vtable.buddy_info_updated=linphone_gtk_buddy_info_updated;
|
||||
vtable.call_encryption_changed=linphone_gtk_call_encryption_changed;
|
||||
|
|
@ -846,7 +847,7 @@ static gboolean launch_contact_provider_search(void *userdata)
|
|||
);
|
||||
|
||||
if(search)
|
||||
belle_sip_object_ref(search);
|
||||
linphone_contact_search_ref(search);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "mediastreamer2/mscommon.h"
|
||||
#include "ortp/ortp_srtp.h"
|
||||
#include "belle-sip/belle-sip.h"
|
||||
|
||||
#ifndef LINPHONE_PUBLIC
|
||||
#define LINPHONE_PUBLIC MS2_PUBLIC
|
||||
|
|
@ -224,6 +225,11 @@ typedef struct SalMessage{
|
|||
time_t time;
|
||||
}SalMessage;
|
||||
|
||||
typedef struct SalIsComposing {
|
||||
const char *from;
|
||||
const char *text;
|
||||
} SalIsComposing;
|
||||
|
||||
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5
|
||||
|
||||
SalMediaDescription *sal_media_description_new();
|
||||
|
|
@ -241,11 +247,7 @@ typedef struct SalOpBase{
|
|||
Sal *root;
|
||||
char *route; /*or request-uri for REGISTER*/
|
||||
MSList* route_addresses; /*list of SalAddress* */
|
||||
#ifndef USE_BELLESIP
|
||||
char *contact;
|
||||
#else
|
||||
SalAddress* contact_address;
|
||||
#endif
|
||||
char *from;
|
||||
SalAddress* from_address;
|
||||
char *to;
|
||||
|
|
@ -279,7 +281,7 @@ typedef enum SalReason{
|
|||
SalReasonTemporarilyUnavailable,
|
||||
SalReasonNotFound,
|
||||
SalReasonDoNotDisturb,
|
||||
SalReasonMedia,
|
||||
SalReasonUnsupportedContent,
|
||||
SalReasonForbidden,
|
||||
SalReasonUnknown,
|
||||
SalReasonServiceUnavailable,
|
||||
|
|
@ -390,6 +392,7 @@ typedef void (*SalOnDtmfReceived)(SalOp *op, char dtmf);
|
|||
typedef void (*SalOnRefer)(Sal *sal, SalOp *op, const char *referto);
|
||||
typedef void (*SalOnTextReceived)(SalOp *op, const SalMessage *msg);
|
||||
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus status);
|
||||
typedef void (*SalOnIsComposingReceived)(SalOp *op, const SalIsComposing *is_composing);
|
||||
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
|
||||
typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status, SalError error, SalReason reason);
|
||||
typedef void (*SalOnNotify)(SalOp *op, SalSubscribeStatus status, const char *event, const SalBody *body);
|
||||
|
|
@ -425,6 +428,7 @@ typedef struct SalCallbacks{
|
|||
SalOnRefer refer_received;
|
||||
SalOnTextReceived text_received;
|
||||
SalOnTextDeliveryUpdate text_delivery_update;
|
||||
SalOnIsComposingReceived is_composing_received;
|
||||
SalOnNotifyRefer notify_refer;
|
||||
SalOnSubscribeReceived subscribe_received;
|
||||
SalOnSubscribeClosed subscribe_closed;
|
||||
|
|
@ -690,6 +694,8 @@ LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
|
|||
LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file);
|
||||
LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal);
|
||||
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
|
||||
belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name);
|
||||
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer);
|
||||
|
||||
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype);
|
||||
/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/
|
||||
|
|
|
|||
|
|
@ -80,6 +80,17 @@ public interface LinphoneChatRoom {
|
|||
* Deletes all the messages associated with the peer of this chat room
|
||||
*/
|
||||
void deleteHistory();
|
||||
|
||||
/**
|
||||
* Notify the destination of the chat message being composed that the user is typing a new message.
|
||||
*/
|
||||
void compose();
|
||||
|
||||
/**
|
||||
* Tells whether the remote is currently composing a message.
|
||||
* @return true if the remote is currently composing a message, false otherwise.
|
||||
*/
|
||||
boolean isRemoteComposing();
|
||||
|
||||
/**
|
||||
* Marks all the messages in this conversation as read
|
||||
|
|
|
|||
|
|
@ -91,6 +91,13 @@ public interface LinphoneCoreListener {
|
|||
*/
|
||||
void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message);
|
||||
|
||||
/**
|
||||
* invoked when a composing notification is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in the conversation.
|
||||
*/
|
||||
void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr);
|
||||
|
||||
/**
|
||||
* invoked when a new dtmf is received
|
||||
* @param lc LinphoneCore
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
|
|||
private native void destroy(long ptr);
|
||||
private native int getUnreadMessagesCount(long ptr);
|
||||
private native void deleteHistory(long ptr);
|
||||
private native void compose(long ptr);
|
||||
private native boolean isRemoteComposing(long ptr);
|
||||
private native void markAsRead(long ptr);
|
||||
private native void deleteMessage(long room, long message);
|
||||
private native void updateUrl(long room, long message);
|
||||
|
|
@ -87,6 +89,14 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
|
|||
public void deleteHistory() {
|
||||
deleteHistory(nativePtr);
|
||||
}
|
||||
|
||||
public void compose() {
|
||||
compose(nativePtr);
|
||||
}
|
||||
|
||||
public boolean isRemoteComposing() {
|
||||
return isRemoteComposing(nativePtr);
|
||||
}
|
||||
|
||||
public void markAsRead() {
|
||||
markAsRead(nativePtr);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Libraries and headers required to develop software with linphone.
|
|||
%if !%{video}
|
||||
--disable-video \
|
||||
%endif
|
||||
--disable-tests --docdir=%{_docdir} --enable-ipv6 --enable-static --enable-external-mediastreamer --enable-external-ortp
|
||||
--disable-tests --docdir=%{_docdir} --enable-ipv6 --enable-static --enable-external-mediastreamer --enable-external-ortp --enable-ldap
|
||||
%__make %{?_smp_mflags}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 4103f0b1d7757558d06e6e32b657308bb2556c9b
|
||||
Subproject commit ce1127bbf74a1bc1113a048195db3cf2ed49c946
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 37b81a118760caa22a5a89d56945acea9aa52523
|
||||
Subproject commit d4241929983c8f0114f8de04dca6ecbc42b9607e
|
||||
|
|
@ -11,7 +11,7 @@ status-orange.png \
|
|||
status-red.png \
|
||||
status-offline.png \
|
||||
call.png \
|
||||
chat.png active_chat.png\
|
||||
chat.png active_chat.png composing_chat.png composing_active_chat.png\
|
||||
chat_message_inprogress.png chat_message_delivered.png chat_message_not_delivered.png\
|
||||
contact-orange.png dialer-orange.png history-orange.png\
|
||||
startcall-green.png startcall-small.png stopcall-red.png stopcall-small.png addcall-green.png linphone.icns \
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
BIN
pixmaps/composing_active_chat.png
Normal file
BIN
pixmaps/composing_active_chat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
BIN
pixmaps/composing_chat.png
Normal file
BIN
pixmaps/composing_chat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -27,6 +27,7 @@ gtk/loginframe.c
|
|||
[type: gettext/glade]gtk/call_statistics.ui
|
||||
[type: gettext/glade]gtk/tunnel_config.ui
|
||||
[type: gettext/glade]gtk/keypad.ui
|
||||
[type: gettext/glade]gtk/ldap.ui
|
||||
coreapi/linphonecore.c
|
||||
coreapi/misc.c
|
||||
coreapi/presence.c
|
||||
|
|
|
|||
17
share/CMakeLists.txt
Normal file
17
share/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
install(FILES archived-rootca.pem
|
||||
RENAME rootca.pem
|
||||
COMPONENT COMP_liblinphone
|
||||
DESTINATION share/linphone
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
|
||||
install(FILES ringback.wav
|
||||
COMPONENT COMP_liblinphone
|
||||
DESTINATION share/sounds/linphone
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
|
||||
add_subdirectory(rings)
|
||||
|
||||
install(FILES ../mediastreamer2/src/voip/nowebcamCIF.jpg
|
||||
COMPONENT COMP_liblinphone
|
||||
DESTINATION share/images
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
4
share/rings/CMakeLists.txt
Normal file
4
share/rings/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
install(FILES oldphone.wav toy-mono.wav
|
||||
COMPONENT COMP_liblinphone
|
||||
DESTINATION share/sounds/linphone/rings
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
|
|
@ -23,11 +23,11 @@ liblinphone_tester_SOURCES= liblinphone_tester.c liblinphone_tester.h\
|
|||
|
||||
AM_CPPFLAGS=-I$(top_srcdir)/include -I$(top_srcdir)/coreapi
|
||||
|
||||
LDADD=$(top_builddir)/coreapi/liblinphone.la $(BELLESIP_LIBS)
|
||||
LDADD=$(top_builddir)/coreapi/liblinphone.la $(BELLESIP_LIBS) $(LIBXML2_LIBS)
|
||||
|
||||
AM_LDFLAGS=$(CUNIT_LIBS)
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS)
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS)
|
||||
|
||||
test: liblinphone_tester
|
||||
./liblinphone_tester --config $(abs_srcdir)
|
||||
|
|
|
|||
|
|
@ -331,9 +331,9 @@ static void call_failed_because_of_codecs(void) {
|
|||
linphone_call_ref(out_call);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
|
||||
|
||||
/*flexisip will retain the 415 until the "urgent reply" timeout arrives.*/
|
||||
/*flexisip will retain the 488 until the "urgent reply" timeout arrives.*/
|
||||
CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,6000));
|
||||
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonMedia);
|
||||
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0);
|
||||
|
||||
linphone_call_unref(out_call);
|
||||
|
|
@ -1387,6 +1387,41 @@ static void call_established_with_rejected_reinvite(void) {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_established_with_rejected_incoming_reinvite(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
||||
/*wait for ACK to be transmitted before going to reINVITE*/
|
||||
wait_for_until(marie->lc,pauline->lc,NULL,0,1000);
|
||||
|
||||
linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/
|
||||
linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/
|
||||
|
||||
linphone_core_update_call(marie->lc
|
||||
,linphone_core_get_current_call(marie->lc)
|
||||
,linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)));
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
|
||||
CU_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(marie->lc)),LinphoneReasonNotAcceptable);
|
||||
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallStreamsRunning,1);
|
||||
check_call_state(pauline,LinphoneCallStreamsRunning);
|
||||
check_call_state(marie,LinphoneCallStreamsRunning);
|
||||
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void call_established_with_rejected_reinvite_with_error(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
|
@ -1399,8 +1434,8 @@ static void call_established_with_rejected_reinvite_with_error(void) {
|
|||
sal_enable_unconditional_answer(marie->lc->sal,TRUE);
|
||||
|
||||
linphone_core_update_call( pauline->lc
|
||||
,linphone_core_get_current_call(pauline->lc)
|
||||
,linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)));
|
||||
,linphone_core_get_current_call(pauline->lc)
|
||||
,linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)));
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
|
|
@ -1460,6 +1495,7 @@ test_t call_tests[] = {
|
|||
{ "Call with custom headers",call_with_custom_headers},
|
||||
{ "Call established with rejected INFO",call_established_with_rejected_info},
|
||||
{ "Call established with rejected RE-INVITE",call_established_with_rejected_reinvite},
|
||||
{ "Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite },
|
||||
{ "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -136,9 +136,11 @@ bool_t wait_for_until(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int va
|
|||
ms_list_free(lcs);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
|
||||
return wait_for_until(lc_1, lc_2,counter,value,3000);
|
||||
}
|
||||
|
||||
bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) {
|
||||
int retry=0;
|
||||
MSList* iterator;
|
||||
|
|
@ -189,6 +191,7 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f
|
|||
mgr->v_table.call_state_changed=call_state_changed;
|
||||
mgr->v_table.text_received=text_message_received;
|
||||
mgr->v_table.message_received=message_received;
|
||||
mgr->v_table.is_composing_received=is_composing_received;
|
||||
mgr->v_table.new_subscription_requested=new_subscription_requested;
|
||||
mgr->v_table.notify_presence_received=notify_presence_received;
|
||||
mgr->v_table.transfer_state_changed=linphone_transfer_state_changed;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ typedef struct _stats {
|
|||
int number_of_LinphoneMessageInProgress;
|
||||
int number_of_LinphoneMessageDelivered;
|
||||
int number_of_LinphoneMessageNotDelivered;
|
||||
|
||||
int number_of_LinphoneIsComposingActiveReceived;
|
||||
int number_of_LinphoneIsComposingIdleReceived;
|
||||
|
||||
int number_of_IframeDecoded;
|
||||
|
||||
|
|
@ -194,6 +195,7 @@ void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered,
|
|||
void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf);
|
||||
void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message);
|
||||
void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message);
|
||||
void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room);
|
||||
void info_message_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg);
|
||||
void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ sip_tls_port=5083
|
|||
default_proxy=0
|
||||
ping_with_options=0
|
||||
register_only_when_network_is_up=0
|
||||
composing_idle_timeout=1
|
||||
|
||||
[auth_info_0]
|
||||
username=marie
|
||||
|
|
|
|||
|
|
@ -44,6 +44,15 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess
|
|||
}
|
||||
}
|
||||
|
||||
void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
|
||||
stats *counters = get_stats(lc);
|
||||
if (room->remote_is_composing == LinphoneIsComposingActive) {
|
||||
counters->number_of_LinphoneIsComposingActiveReceived++;
|
||||
} else {
|
||||
counters->number_of_LinphoneIsComposingIdleReceived++;
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_chat_message_state_change(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
|
||||
LinphoneCore* lc=(LinphoneCore*)ud;
|
||||
stats* counters = get_stats(lc);
|
||||
|
|
@ -264,6 +273,24 @@ static void info_message_with_body(){
|
|||
info_message_with_args(TRUE);
|
||||
}
|
||||
|
||||
static void is_composing_notification(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc, to);
|
||||
int dummy = 0;
|
||||
|
||||
ms_free(to);
|
||||
linphone_chat_room_compose(chat_room);
|
||||
wait_for_until(pauline->lc, marie->lc, &dummy, 1, 1500); /*just to sleep while iterating*/
|
||||
linphone_chat_room_send_message(chat_room, "Composing a message");
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 2));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
test_t message_tests[] = {
|
||||
{ "Text message", text_message },
|
||||
{ "Text message with privacy", text_message_with_privacy },
|
||||
|
|
@ -272,7 +299,8 @@ test_t message_tests[] = {
|
|||
{ "Text message with send error", text_message_with_send_error },
|
||||
{ "Text message with external body", text_message_with_external_body },
|
||||
{ "Info message", info_message },
|
||||
{ "Info message with body", info_message_with_body }
|
||||
{ "Info message with body", info_message_with_body },
|
||||
{ "IsComposing notification", is_composing_notification }
|
||||
};
|
||||
|
||||
test_suite_t message_test_suite = {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ sip_tls_port=5073
|
|||
default_proxy=0
|
||||
ping_with_options=0
|
||||
register_only_when_network_is_up=0
|
||||
composing_idle_timeout=1
|
||||
|
||||
[auth_info_0]
|
||||
username=pauline
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue