Commit 24b416cd authored by jehan's avatar jehan

Merge remote-tracking branch 'origin/master' into dev_lime_v2

parents 82c71e2b f7a6c72b
......@@ -210,9 +210,6 @@ if(ANDROID)
endif()
set(LINPHONE_LDFLAGS "${BELLESIP_LDFLAGS} ${MEDIASTREAMER2_LDFLAGS}")
if(BELCARD_FOUND AND APPLE)
set(LINPHONE_LDFLAGS "${LINPHONE_LDFLAGS} -stdlib=libc++")
endif()
# include_directories must be called only UNDER THIS LINE in order to use our
# projects submodules first (we do NOT want to have system headers in first position)
......
## Process this file with automake to produce Makefile.in
# let make re-run automake upon need
ACLOCAL_AMFLAGS = -I m4 $(ACLOCAL_MACOS_FLAGS)
SUBDIRS = build m4 pixmaps po @ORTP_DIR@ @MS2_DIR@ \
coreapi console gtk share scripts tools daemon tester include
GITVERSION=`cd $(top_srcdir) && git describe --always || echo $(VERSION)`
ACLOCAL_FLAGS=-I$(top_srcdir)/m4
OPTIONAL_SOUNDS=\
share/sounds/linphone/rings/synth.wav \
share/sounds/linphone/rings/tapping.wav \
share/sounds/linphone/rings/orig.wav \
share/sounds/linphone/rings/sweet.wav \
share/sounds/linphone/rings/rock.wav
INSTALLDIR=$(abs_top_builddir)/linphone-install
INSTALLDIR_WITH_PREFIX=$(INSTALLDIR)/$(prefix)
ZIPFILE=$(abs_top_builddir)/$(PACKAGE)-win32-$(GITVERSION).zip
ZIP_EXCLUDED=include lib \
$(OPTIONAL_SOUNDS)
SDK_ZIPFILE=$(abs_top_builddir)/lib$(PACKAGE)-win32-sdk-$(GITVERSION).zip
SDK_EXCLUDED= \
bin/linphone.exe \
lib/*.la \
share/linphone \
share/pixmaps \
share/locale \
share/gnome \
$(OPTIONAL_SOUNDS)
GTK_PREFIX=/
GTK_THEME=Outcrop
GTK_FILELIST=gtk+-2.24.8.filelist
GTK_FILELIST_PATH=$(abs_top_srcdir)/$(GTK_FILELIST)
LINPHONEDEPS_FILELIST=linphone-deps.filelist
WINBINDIST_FILES=`cat $(abs_top_srcdir)/$(LINPHONEDEPS_FILELIST)`
ISS_SCRIPT=linphone.iss
ISS_SCRIPT_PATH=$(abs_top_srcdir)/$(ISS_SCRIPT)
#path to Inno Setup 5 compiler
ISCC=ISCC.exe
PACKAGE_WIN32_FILELIST=$(PACKAGE)-win32.filelist
PACKAGE_BUNDLE_FILE=$(top_srcdir)/build/macos/$(PACKAGE).bundle
EXTRA_DIST = \
BUGS \
README.arm \
README.mingw \
README.macos.md \
README.md \
autogen.sh \
linphone.spec \
linphone.spec.in \
$(GTK_FILELIST) \
gen-gtkfilelist.sh \
$(LINPHONEDEPS_FILELIST) \
$(ISS_SCRIPT).in \
CMakeLists.txt \
cmake/FindGtkMacIntegration.cmake \
cmake/FindIconv.cmake \
cmake/FindIntl.cmake \
cmake/FindNotify.cmake \
cmake/FindSqlite3.cmake \
cmake/FindXML2.cmake \
cmake/FindZlib.cmake \
cmake/LinphoneConfig.cmake.in \
config.h.cmake \
console/CMakeLists.txt \
coreapi/CMakeLists.txt \
coreapi/gitversion.cmake \
coreapi/help/CMakeLists.txt \
gtk/CMakeLists.txt \
java/CMakeLists.txt \
pixmaps/CMakeLists.txt \
po/CMakeLists.txt \
share/CMakeLists.txt \
share/rings/CMakeLists.txt \
share/rootca.cmake \
tester/CMakeLists.txt \
tools/CMakeLists.txt
DISTCLEANFILES= $(ISS_SCRIPT) $(PACKAGE_WIN32_FILELIST)
CLEANFILES=Portfile Portfile-devel
# `make rpm'
all-local: linphone.spec linphone.iss
linphone.spec: linphone.spec.in
.phony: rpm rpm-novideo rpm-base
rpm-base:
$(MAKE) dist
-rm -f $(PACKAGE)-$(VERSION).tar
gunzip $(PACKAGE)-$(VERSION).tar.gz
#remove ms2 and ortp spec file to make sure linphone spec file is used bu rpmbuild
tar --delete --file=$(PACKAGE)-$(VERSION).tar $(PACKAGE)-$(VERSION)/mediastreamer2/mediastreamer2.spec
tar --delete --file=$(PACKAGE)-$(VERSION).tar $(PACKAGE)-$(VERSION)/oRTP/ortp.spec
gzip $(PACKAGE)-$(VERSION).tar
rpm: rpm-base
# <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=2068410>
TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz
rpm-novideo: rpm-base
# <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=2068410>
TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz --without video
#a zip containing win32 binaries, suitable to generate an installer
if BUILD_TUNNEL
WINBINDIST_FILES+=./bin/libtunnel-0.dll
endif
other-cherrypick:
cd $(GTK_PREFIX) && \
for file in $(WINBINDIST_FILES) ; do \
if test -d $(prefix)/$$file; then \
$(MKDIR_P) $(INSTALLDIR_WITH_PREFIX)/$$file ;\
else \
cp $(prefix)/$$file $(INSTALLDIR_WITH_PREFIX)/$$file ;\
fi \
done
if test -d /mingw/bin ; then \
cp /mingw/bin/libgcc_s*.dll \
/mingw/bin/libstdc++-6.dll \
/mingw/bin/libintl-8.dll \
/mingw/bin/libiconv-2.dll \
/mingw/bin/pthreadGC2.dll \
$(INSTALLDIR_WITH_PREFIX)/bin/. ;\
fi
gtk-cherrypick:
cd $(GTK_PREFIX) && \
for file in `cat $(GTK_FILELIST_PATH)` ; do \
if test -d $(prefix)/$$file; then \
$(MKDIR_P) $(INSTALLDIR_WITH_PREFIX)/$$file ;\
else \
cp $(prefix)/$$file $(INSTALLDIR_WITH_PREFIX)/$$file ;\
fi \
done && \
$(MKDIR_P) $(INSTALLDIR_WITH_PREFIX)/share/themes && \
cp -rf $(prefix)/share/themes/$(GTK_THEME) $(INSTALLDIR_WITH_PREFIX)/share/themes/.
zip:
rm -f $(ZIPFILE)
rm -rf $(INSTALLDIR)
$(MKDIR_P) $(INSTALLDIR)
make install DESTDIR=$(INSTALLDIR)
#remove unwanted linphone stuff
cd $(INSTALLDIR_WITH_PREFIX) && rm -rf $(ZIP_EXCLUDED)
#add gtk dlls and files
make gtk-cherrypick
make other-cherrypick
cp -f $(top_srcdir)/gtk/gtkrc $(INSTALLDIR_WITH_PREFIX)/.
cp -f $(top_srcdir)/README $(INSTALLDIR_WITH_PREFIX)/.
cp -f $(top_srcdir)/COPYING $(INSTALLDIR_WITH_PREFIX)/.
cd $(INSTALLDIR_WITH_PREFIX) && zip -r $(ZIPFILE) *
sdk:
rm -f $(SDK_ZIPFILE)
rm -rf $(INSTALLDIR)
$(MKDIR_P) $(INSTALLDIR)
make install DESTDIR=$(INSTALLDIR)
# remove unwanted stuff (gtk interface)
cd $(INSTALLDIR_WITH_PREFIX) && rm -rf $(SDK_EXCLUDED)
make other-cherrypick
cp -f $(top_srcdir)/README $(INSTALLDIR_WITH_PREFIX)/.
cp -f $(top_srcdir)/COPYING $(INSTALLDIR_WITH_PREFIX)/.
cd $(INSTALLDIR_WITH_PREFIX) && zip -r $(SDK_ZIPFILE) *
filelist: zip
cd $(INSTALLDIR_WITH_PREFIX) && \
rm -f $(PACKAGE_WIN32_FILELIST) && \
for file in `find` ; do \
if ! test -d $$file ; then \
echo "Source: $$file; Destdir: {app}\\`dirname $$file`; Flags: ignoreversion" \
>> $(PACKAGE_WIN32_FILELIST) ;\
fi \
done
### LOCALIZATION
pull-transifex:
tx pull -af
push-transifex:
$(MAKE) -C po update-po
tx push -s -f --no-interactive
### WINDOWS
setup.exe: filelist
cp $(ISS_SCRIPT) $(INSTALLDIR_WITH_PREFIX)/.
cd $(INSTALLDIR_WITH_PREFIX) && \
$(ISCC) $(ISS_SCRIPT)
mv $(INSTALLDIR_WITH_PREFIX)/Output/setup.exe $(PACKAGE)-setup-$(GITVERSION).exe
rm -rf $(INSTALLDIR_WITH_PREFIX)/Output
rm -f $(INSTALLDIR_WITH_PREFIX)/$(PACKAGE_WIN32_FILELIST)
rm -f $(INSTALLDIR_WITH_PREFIX)/$(ISS_SCRIPT)
###
newdate:
cd gtk && $(MAKE) newdate
if HAVE_MD5SUM
GEN_MD5=`$(MD5SUM) linphone-$(VERSION).tar.gz | awk {'print $$4'}`
else
GEN_MD5=`$(MD5SUM) linphone-$(VERSION).tar.gz | awk {'print $$1'}`
endif
Portfile: $(top_srcdir)/scripts/Portfile.tmpl dist
sed -e 's/\@VERSION\@/$(LINPHONE_VERSION)/g' \
-e 's/\@LINPHONE_MD5\@/$(GEN_MD5)/' < $< > $@
Portfile-devel: $(top_srcdir)/scripts/Portfile-devel.tmpl dist
sed -e 's/\@VERSION\@/$(LINPHONE_VERSION)/g' \
-e 's/\@LINPHONE_MD5\@/$(GEN_MD5)/' < $< > $@
### MAC
MACAPPNAME=Linphone.app
MACAPPZIP=$(PACKAGE)-$(GITVERSION).app.zip
MACAPPDMG=$(PACKAGE)-$(GITVERSION).dmg
MACAPPPKG=$(PACKAGE)-$(GITVERSION).pkg
BUNDLEPREFIX=./
BUNDLEDIR=$(BUNDLEPREFIX)$(MACAPPNAME)
#a path prefix where additional libs can be cherry-picked by the bundler.
LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX=/usr/local
Linphone.app:
rm -rf $(INSTALLDIR)
$(MKDIR_P) $(INSTALLDIR)
make install DESTDIR=$(INSTALLDIR)
BUNDLE_PREFIX=$(BUNDLEPREFIX) \
LINPHONE_INSTALL_PREFIX=$(INSTALLDIR_WITH_PREFIX) \
LIBLINPHONE_INSTALL_PREFIX=$(INSTALLDIR_WITH_PREFIX) \
MS2_PLUGINS_INSTALL_PREFIX=$(prefix) \
LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX=$(LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX) \
gtk-mac-bundler $(PACKAGE_BUNDLE_FILE)
patch ${BUNDLEDIR}/Contents/Resources/share/themes/Quartz/gtk-2.0/gtkrc ${srcdir}/build/macos/quartz-theme-gtkrc.patch
rm -f ${BUNDLEDIR}/Contents/Resources/lib/libopenh264*
bundle: $(MACAPPNAME)
cd $(BUNDLEDIR)/.. && rm -f $(MACAPPZIP) && zip -r $(MACAPPZIP) $(MACAPPNAME) && cd -
cd $(BUNDLEDIR)/.. && rm -f $(MAXAPPDMG) && hdiutil create $(MACAPPDMG) -srcfolder $(MACAPPNAME) -ov && cd -
signed-bundle: $(MACAPPNAME)
codesign --deep -s "$(BUNDLE_SIGNING_ID)" $(BUNDLEDIR)
cd $(BUNDLEDIR)/.. && rm -f $(MAXAPPDMG) && hdiutil create $(MACAPPDMG) -srcfolder $(MACAPPNAME) -ov && cd -
pkg: $(MACAPPNAME)
rm -rf ./packaging
mkdir -p ./packaging
cp ${srcdir}/COPYING ./packaging
cp ${srcdir}/pixmaps/linphone.png ./packaging
pkgbuild --install-location /Applications --scripts ${srcdir}/build/macos/pkg-scripts --component $(MACAPPNAME) ./packaging/linphone.pkg
productbuild --resources . --distribution ${srcdir}/build/macos/pkg-distribution.xml --package-path ./packaging $(MACAPPPKG)
signed-pkg: pkg
mv $(MACAPPPKG) $(MACAPPPKG).tmp
productsign --sign "$(BUNDLE_SIGNING_ID)" $(MACAPPPKG).tmp $(MACAPPPKG)
rm -f $(MACAPPPKG).tmp
###
### CLEAN
clean-local:
rm -rf $(BUNDLEDIR)
discovery:
touch specs.c
$(CC) --include $(top_builddir)/config.h \
$(TUNNEL_CFLAGS) $(CFLAGS) $(MEDIASTREAMER2_CFLAGS) $(ORTP_CFLAGS) $(SIPSTACK_CFLAGS) $(BCTOOLBOXTESTER_CFLAGS) -E -P -v -dD specs.c
.PHONY: $(MACAPPNAME) pkg
......@@ -6,7 +6,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>linphone</string>
<string>${MACOSX_FRAMEWORK_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
......
......@@ -64,7 +64,7 @@ develop programs using the liblinphone library.
%setup -n %{name}-%{version}%{?build_number_ext}
%build
%{expand:%%%cmake_name} . -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ -DCMAKE_INSTALL_LIBDIR:PATH=%{_libdir} -DCMAKE_PREFIX_PATH:PATH=%{_prefix} @RPM_ALL_CMAKE_OPTIONS@
%{expand:%%%cmake_name} . -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ -DCMAKE_PREFIX_PATH:PATH=%{_prefix} @RPM_ALL_CMAKE_OPTIONS@
make %{?_smp_mflags}
%install
......@@ -86,7 +86,7 @@ rm -rf $RPM_BUILD_ROOT
%postun -p /sbin/ldconfig
%files
%files
%defattr(-,root,root)
%doc ChangeLog.md COPYING README.md
%if @ENABLE_DAEMON@ || @ENABLE_CONSOLE_UI@ || @ENABLE_TOOLS@
......@@ -121,7 +121,12 @@ rm -rf $RPM_BUILD_ROOT
%changelog
* Tue Nov 27 2018 ronan.abhamon <ronan.abhamon@belledonne-communications.com>
- Do not set CMAKE_INSTALL_LIBDIR and never with _libdir!
* Thu Jul 13 2017 jehan.monnier <jehan.monnier@linphone.org>
- cmake port
* Mon Aug 19 2013 jehan.monnier <jehan.monnier@linphone.org>
- Initial RPM release.
......@@ -39,6 +39,7 @@ endif()
add_executable(linphonec ${LINPHONEC_SOURCE_FILES})
target_link_libraries(linphonec ${LINPHONE_LIBS_FOR_TOOLS} ${BCTOOLBOX_CORE_LIBRARIES} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${XSD_LIBRARIES})
set_target_properties(linphonec PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
set_target_properties(linphonec PROPERTIES LINKER_LANGUAGE CXX)
if(INTL_FOUND)
target_link_libraries(linphonec ${INTL_LIBRARIES})
......@@ -55,6 +56,7 @@ endif()
add_executable(linphonecsh ${LINPHONECSH_SOURCE_FILES})
target_link_libraries(linphonecsh ${LINPHONE_LIBS_FOR_TOOLS} ${BCTOOLBOX_CORE_LIBRARIES} ${ORTP_LIBRARIES})
set_target_properties(linphonecsh PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
set_target_properties(linphonecsh PROPERTIES LINKER_LANGUAGE CXX)
set(INSTALL_TARGETS linphonec linphonecsh)
if(WIN32)
......
......@@ -128,9 +128,6 @@ if(BELCARD_FOUND)
if(NOT MSVC)
list(APPEND STRICT_OPTIONS_CXX "-std=c++11")
endif()
if(APPLE)
list(APPEND STRICT_OPTIONS_CXX "-stdlib=libc++")
endif()
else()
list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c)
endif()
......
......@@ -420,8 +420,9 @@ void TunnelManager::onIterate(){
}
/*invoked from linphone_core_iterate() */
void TunnelManager::sOnIterate(TunnelManager *zis){
bool_t TunnelManager::sOnIterate(TunnelManager *zis){
zis->onIterate();
return TRUE;
}
LinphoneTunnelMode TunnelManager::getMode() const {
......
......@@ -205,7 +205,7 @@ namespace belledonnecomm {
static int customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen);
static void tunnelCallback(bool connected, void *zis);
static void tunnelCallback2(TunnelDirection direction, bool connected, void *zis);
static void sOnIterate(TunnelManager *zis);
static bool_t sOnIterate(TunnelManager *zis);
static void sUdpMirrorClientCallback(bool result, void* data);
static void networkReachableCb(LinphoneCore *lc, bool_t reachable);
......
......@@ -106,9 +106,9 @@ static char* _get_identity(const LinphoneAccountCreator *creator) {
LinphoneAddress* addr;
addr = linphone_proxy_config_normalize_sip_uri(proxy, creator->username ? creator->username : creator->phone_number);
if (addr == NULL) {
if (creator->username && creator->domain) {
char *url = ms_strdup_printf("sip:%s@%s", creator->username, creator->domain);
if (addr == NULL || (creator->domain && strcmp(linphone_address_get_domain(addr), creator->domain) != 0)) {
if ((creator->username || creator->phone_number) && creator->domain) {
char *url = ms_strdup_printf("sip:%s@%s", creator->username ? creator->username : creator->phone_number, creator->domain);
addr = linphone_address_new(url);
ms_free(url);
if (addr == NULL) {
......@@ -1332,6 +1332,7 @@ LinphoneAccountCreatorStatus linphone_account_creator_update_password_linphone(L
}
return LinphoneAccountCreatorStatusMissingArguments;
}
bctbx_free(identity);
if (creator->xmlrpc_session) {
const char *username = creator->username ? creator->username : creator->phone_number;
......
......@@ -668,6 +668,45 @@ bctbx_list_t * linphone_core_get_call_history_for_address(LinphoneCore *lc, cons
return clsres.result;
}
bctbx_list_t *linphone_core_get_call_history_2(
LinphoneCore *lc,
const LinphoneAddress *peer_addr,
const LinphoneAddress *local_addr
) {
char *buf;
char *peer_addr_str;
char *local_addr_str;
uint64_t begin, end;
CallLogStorageResult clsres;
if (!lc || !lc->logs_db || !peer_addr || !local_addr) return NULL;
peer_addr_str = bctbx_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(peer_addr)->asStringUriOnly().c_str());
local_addr_str = bctbx_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(local_addr)->asStringUriOnly().c_str());
buf = sqlite3_mprintf(
"SELECT * FROM call_history WHERE "
"(caller LIKE '%%%q%%' AND callee LIKE '%%%q%%' AND direction = 0) OR "
"(caller LIKE '%%%q%%' AND callee LIKE '%%%q%%' AND direction = 1) "
"ORDER BY id DESC",
local_addr_str,
peer_addr_str,
peer_addr_str,
local_addr_str
);
clsres.core = lc;
clsres.result = NULL;
begin = ortp_get_cur_time_ms();
linphone_sql_request_call_log(lc->logs_db, buf, &clsres);
end = ortp_get_cur_time_ms();
bctbx_message("%s(): completed in %i ms", __FUNCTION__, (int)(end - begin));
sqlite3_free(buf);
bctbx_free(peer_addr_str);
bctbx_free(local_addr_str);
return clsres.result;
}
LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) {
char *buf;
uint64_t begin,end;
......
......@@ -108,7 +108,10 @@ static void call_received(SalCallOp *h) {
h->release();
return;
}
IdentityAddress confAddr = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb->findOneToOneConferenceChatRoomAddress(from, identAddresses.front());
const char *endToEndEncryptedStr = sal_custom_header_find(h->getRecvCustomHeaders(), "End-To-End-Encrypted");
bool encrypted = endToEndEncryptedStr && strcmp(endToEndEncryptedStr, "true") == 0;
IdentityAddress confAddr = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb->findOneToOneConferenceChatRoomAddress(from, identAddresses.front(), encrypted);
if (confAddr.isValid()) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ConferenceId(confAddr, confAddr));
L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->confirmRecreation(h);
......@@ -119,7 +122,9 @@ static void call_received(SalCallOp *h) {
}
// TODO: handle media conference creation if the "text" feature tag is not present
return;
} else if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
}
if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
if (linphone_core_conference_server_enabled(lc)) {
......@@ -623,7 +628,7 @@ static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus
static void message_delivery_update(SalOp *op, SalMessageDeliveryStatus status) {
auto lc = reinterpret_cast<LinphoneCore *>(op->getSal()->getUserPointer());
if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) {
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
static_cast<SalMessageOp *>(op)->reply(SalReasonDeclined);
return;
}
......
......@@ -1730,3 +1730,23 @@ const char * linphone_friend_sip_uri_to_phone_number(LinphoneFriend *lf, const c
void linphone_friend_clear_presence_models(LinphoneFriend *lf) {
lf->presence_models = bctbx_list_free_with_data(lf->presence_models, (bctbx_list_free_func)free_friend_presence);
}
int linphone_friend_get_capabilities(const LinphoneFriend *lf) {
return lf->capabilities;
}
namespace {
const std::unordered_map<std::string, LinphoneFriendCapability> StringToCapability{
{ "groupchat", LinphoneFriendCapabilityGroupChat },
{ "lime", LinphoneFriendCapabilityLimeX3dh }
};
}
void linphone_friend_add_capability(LinphoneFriend *lf, const char *capability_name) {
auto it = StringToCapability.find(capability_name);
if (it == StringToCapability.cend()) {
bctbx_error("Invalid capability %s for friend [%p]", capability_name, lf);
} else {
bctbx_debug("Adding capability %s to friend [%p]", capability_name, lf);
lf->capabilities |= it->second;
}
}
......@@ -323,7 +323,19 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
}
if (lf) {
const char *phone_number = linphone_friend_sip_uri_to_phone_number(lf, uri);
unsigned int nb_services = linphone_presence_model_get_nb_services((LinphonePresenceModel *)presence);
for (unsigned int i = 0; i < nb_services; i++) {
LinphonePresenceService *service = linphone_presence_model_get_nth_service((LinphonePresenceModel *)presence, i);
bctbx_list_t *services_descriptions = linphone_presence_service_get_service_descriptions(service);
while (services_descriptions) {
char *description = (char *)bctbx_list_get_data(services_descriptions);
linphone_friend_add_capability(lf, description);
services_descriptions = bctbx_list_next(services_descriptions);
}
}
lf->presence_received = TRUE;
if (phone_number) {
char *presence_address = linphone_presence_model_get_contact((LinphonePresenceModel *)presence);
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(presence_address, linphone_friend_ref(lf));
......@@ -665,7 +677,7 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *
}
static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) {
if (cdc && cdc->friend_list->cbs->sync_state_changed_cb) {
if (cdc && cdc->friend_list->cbs && cdc->friend_list->cbs->sync_state_changed_cb) {
cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, success ? LinphoneFriendListSyncSuccessful : LinphoneFriendListSyncFailure, msg);
}
linphone_carddav_context_destroy(cdc);
......
......@@ -25,6 +25,7 @@ if (ENABLE_DOC)
set(doc_output_dir ${CMAKE_CURRENT_BINARY_DIR}/build)
set(reference_doc_source_dir ${doc_source_dir}/reference)
set(static_documentation_files
guides/android_portability.rst
guides/authentication.rst
guides/buddy_list.rst
guides/call_control.rst
......
Android portability
===============
Video
-----
To be able to display remote and locally captured video streams on Android, you have to give the Core 2 TextureViews.
These objects must be given using :java:meth:`setNativeVideoWindowId` and :java:meth:`setNativePreviewWindowId`.
Here's the complete code:
.. code-block:: java
Core mCore; // Get it the way you prefer
TextureView mVideoView = view.findViewById(R.id.videoSurface);
TextureView mCaptureView = view.findViewById(R.id.videoCaptureSurface);
mCore.setNativeVideoWindowId(mVideoView);
mCore.setNativePreviewWindowId(mCaptureView);
\ No newline at end of file
......@@ -47,6 +47,7 @@ Beginners' guides
guides/event_api
guides/misc
guides/ios_portability
guides/android_portability
Code samples
......
This diff is collapsed.
......@@ -48,6 +48,7 @@ struct _LinphonePresenceService {
char *contact;
bctbx_list_t *notes; /**< A list of _LinphonePresenceNote structures. */
time_t timestamp;
bctbx_list_t *service_descriptions;
};
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphonePresenceService);
......@@ -800,6 +801,19 @@ LinphoneStatus linphone_presence_service_set_contact(LinphonePresenceService *se
return 0;
}
bctbx_list_t * linphone_presence_service_get_service_descriptions(const LinphonePresenceService *service) {
return service->service_descriptions;
}
LinphoneStatus linphone_presence_service_set_service_descriptions(LinphonePresenceService *service, bctbx_list_t *descriptions) {
if (!service) return -1;
if (service->service_descriptions)
bctbx_list_free_with_data(service->service_descriptions, bctbx_free);
service->service_descriptions = descriptions;
return 0;
}
unsigned int linphone_presence_service_get_nb_notes(const LinphonePresenceService *service) {
return (unsigned int)bctbx_list_size(service->notes);
}
......@@ -1262,6 +1276,7 @@ static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, Lin
char *contact_str;
LinphonePresenceBasicStatus basic_status;
int i;
xmlXPathObjectPtr service_descriptions;
service_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, service_prefix);
if ((service_object != NULL) && (service_object->nodesetval != NULL)) {
......@@ -1298,16 +1313,33 @@ static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, Lin
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/@id", service_prefix, i);
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));
if (contact_str != NULL) linphone_presence_service_set_contact(service, contact_str);
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/oma-pres:service-description", service_prefix, i);
service_descriptions = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str);
bctbx_list_t *services = nullptr;
if (service_descriptions && service_descriptions->nodesetval) {
for (int j = 1; j <= service_descriptions->nodesetval->nodeNr; j++) {
char *service_id = nullptr;
linphone_xml_xpath_context_set_node(xml_ctx, xmlXPathNodeSetItem(service_descriptions->nodesetval, j-1));
service_id = linphone_get_xml_text_content(xml_ctx, "./oma-pres:service-id");
if (service_id) {
services = bctbx_list_append(services, ms_strdup(service_id));
linphone_free_xml_text_content(service_id);
}
}
}
if (service) {
if (timestamp_str) presence_service_set_timestamp(service, parse_timestamp(timestamp_str));
if (contact_str) linphone_presence_service_set_contact(service, contact_str);
if (services) linphone_presence_service_set_service_descriptions(service, services);
process_pidf_xml_presence_service_notes(xml_ctx, service, (unsigned int)i);
linphone_presence_model_add_service(model, service);
linphone_presence_service_unref(service);
}
if (timestamp_str != NULL) linphone_free_xml_text_content(timestamp_str);
if (contact_str != NULL) linphone_free_xml_text_content(contact_str);
if (service_id_str != NULL) linphone_free_xml_text_content(service_id_str);
if (timestamp_str) linphone_free_xml_text_content(timestamp_str);
if (contact_str) linphone_free_xml_text_content(contact_str);
if (service_id_str) linphone_free_xml_text_content(service_id_str);
linphone_free_xml_text_content(basic_status_str);
}
}
......@@ -1506,6 +1538,7 @@ static LinphonePresenceModel * process_pidf_xml_presence_notification(xmlparsing
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"dm", (const xmlChar *)"urn:ietf:params:xml:ns:pidf:data-model");
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"rpid", (const xmlChar *)"urn:ietf:params:xml:ns:pidf:rpid");
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"pidfonline", (const xmlChar *)"http://www.linphone.org/xsds/pidfonline.xsd");
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"oma-pres", (const xmlChar *)"urn:oma:xml:prs:pidf:oma-pres");
err = process_pidf_xml_presence_services(xml_ctx, model);
if (err == 0) {
err = process_pidf_xml_presence_persons(xml_ctx, model);
......@@ -1993,8 +2026,11 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
}
}else{
ms_message("But this person is not part of our friend list, so we don't care.");
/*
* This case may happen when a friend has been removed from FriendList, in which case it its presence is no longer managed.
* We don't have to release() or unref() the op, because it is still hold by the detached LinphoneFriend.
*/
linphone_presence_model_unref(presence);
op->release();
return ;
}
if (ss==SalSubscribeTerminated){
......
......@@ -169,6 +169,7 @@ void linphone_friend_add_incoming_subscription(LinphoneFriend *lf, LinphonePriva
void linphone_friend_remove_incoming_subscription(LinphoneFriend *lf, LinphonePrivate::SalOp *op);
const char * linphone_friend_phone_number_to_sip_uri(LinphoneFriend *lf, const char *phone_number);
const char * linphone_friend_sip_uri_to_phone_number(LinphoneFriend *lf, const char *uri);
void linphone_friend_add_capability(LinphoneFriend *lf, const char *capability_name);
void linphone_friend_clear_presence_models(LinphoneFriend *lf);
LinphoneFriend *linphone_friend_list_find_friend_by_inc_subscribe(const LinphoneFriendList *list, LinphonePrivate::SalOp *op);
LinphoneFriend *linphone_friend_list_find_friend_by_out_subscribe(const LinphoneFriendList *list, LinphonePrivate::SalOp *op);
......
......@@ -189,6 +189,7 @@ struct _LinphoneFriend{
unsigned int storage_id;
LinphoneFriendList *friend_list;
LinphoneSubscriptionState out_sub_state;
int capabilities = LinphoneFriendCapabilityNone;
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneFriend);
......@@ -292,6 +293,12 @@ struct net_config
bool_t nat_sdp_only;
};