Commit 92202d1d authored by François Grisez's avatar François Grisez

Merge branch 'master' into dev_setup_wizard_glade

parents 74e211b6 5f61842f
......@@ -30,7 +30,7 @@ set(LINPHONE_MICRO_VERSION "5")
set(LINPHONE_VERSION "${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}.${LINPHONE_MICRO_VERSION}")
set(LINPHONE_SO_VERSION "7")
file(GLOB LINPHONE_PO_FILES RELATIVE "${CMAKE_SOURCE_DIR}/po" "${CMAKE_SOURCE_DIR}/po/*.po")
file(GLOB LINPHONE_PO_FILES RELATIVE "${CMAKE_CURRENT_LIST_DIR}/po" "${CMAKE_CURRENT_LIST_DIR}/po/*.po")
string(REGEX REPLACE "([a-zA-Z_]+)\\.po" "\\1" LINPHONE_ALL_LANGS_LIST "${LINPHONE_PO_FILES}")
string(REPLACE ";" " " LINPHONE_ALL_LANGS "${LINPHONE_ALL_LANGS_LIST}")
......@@ -42,6 +42,7 @@ option(ENABLE_DATE "Use build date in internal version number." NO)
option(ENABLE_DOC "Enable documentation generation with Doxygen." YES)
option(ENABLE_GTK_UI "Turn on or off compilation of gtk interface." YES)
option(ENABLE_LDAP "Enable LDAP support." NO)
option(ENABLE_LIME "Enable Instant Messaging Encryption." NO)
option(ENABLE_MSG_STORAGE "Turn on compilation of message storage." YES)
cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI" NO)
option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO)
......@@ -65,27 +66,11 @@ include(CMakePushCheckState)
set(MSVC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/MSVC")
if(MSVC)
list(APPEND CMAKE_REQUIRED_INCLUDES "${MSVC_INCLUDE_DIR}")
if(ENABLE_GTK_UI)
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/intltool_win32.zip")
message(STATUS "Installing intltool")
file(DOWNLOAD http://ftp.acc.umu.se/pub/GNOME/binaries/win32/intltool/0.40/intltool_0.40.4-1_win32.zip "${CMAKE_CURRENT_BINARY_DIR}/intltool_win32.zip" SHOW_PROGRESS)
execute_process(
COMMAND "${CMAKE_COMMAND}" "-E" "tar" "x" "${CMAKE_CURRENT_BINARY_DIR}/intltool_win32.zip"
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
)
endif()
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/gtk+-bundle_win32.zip")
message(STATUS "Installing GTK")
file(DOWNLOAD http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip "${CMAKE_CURRENT_BINARY_DIR}/gtk+-bundle_win32.zip" SHOW_PROGRESS)
execute_process(
COMMAND "${CMAKE_COMMAND}" "-E" "tar" "x" "${CMAKE_CURRENT_BINARY_DIR}/gtk+-bundle_win32.zip"
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
)
endif()
endif()
endif()
# find_package should be invoked here to check for libraries - however do NOT
# call include_directories here (see below)
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
include("${EP_bellesip_CONFIG_DIR}/BelleSIPConfig.cmake")
include("${EP_ms2_CONFIG_DIR}/Mediastreamer2Config.cmake")
......@@ -110,7 +95,11 @@ if(ENABLE_UNIT_TESTS)
endif()
endif()
if(ENABLE_TUNNEL)
find_package(Tunnel)
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
include("${EP_tunnel_CONFIG_DIR}/TunnelConfig.cmake")
else()
find_package(Tunnel)
endif()
if(NOT TUNNEL_FOUND)
message(WARNING "Could not find the tunnel library!")
set(ENABLE_TUNNEL OFF CACHE BOOL "Enable tunnel support." FORCE)
......@@ -130,6 +119,7 @@ if(ENABLE_NOTIFY)
endif()
if(ENABLE_GTK_UI)
if(WIN32)
set(GTK2_DEBUG TRUE)
set(GTK2_ADDITIONAL_SUFFIXES "../lib/glib-2.0/include" "../lib/gtk-2.0/include")
endif()
find_package(GTK2 2.18 REQUIRED gtk)
......@@ -144,17 +134,21 @@ endif()
if(ENABLE_NLS)
find_package(Gettext REQUIRED)
find_package(Intl REQUIRED)
include_directories(${INTL_INCLUDE_DIRS})
endif()
if(ENABLE_CALL_LOGS_STORAGE)
find_package(Sqlite3 REQUIRED)
endif()
if(ENABLE_LIME)
set(HAVE_LIME 1)
endif()
if(UNIX AND NOT APPLE)
include(CheckIncludeFiles)
check_include_files(libudev.h HAVE_LIBUDEV_H)
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)
include_directories(
include/
coreapi/
......@@ -162,33 +156,38 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}/coreapi/
${BELLESIP_INCLUDE_DIRS}
${MEDIASTREAMER2_INCLUDE_DIRS}
${XML2_INCLUDE_DIRS}
)
if(ENABLE_TUNNEL)
include_directories(${TUNNEL_INCLUDE_DIRS})
endif()
include_directories(${XML2_INCLUDE_DIRS})
if(ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIRS})
set(HAVE_ZLIB 1)
endif()
if(SQLITE3_FOUND)
include_directories(${SQLITE3_INCLUDE_DIRS})
add_definitions("-DMSG_STORAGE_ENABLED")
add_definitions("-DCALL_LOGS_STORAGE_ENABLED")
endif()
if(ENABLE_TUNNEL)
include_directories(${TUNNEL_INCLUDE_DIRS})
if(ENABLE_MSG_STORAGE)
add_definitions("-DMSG_STORAGE_ENABLED")
endif()
if(ENABLE_CALL_LOGS_STORAGE)
add_definitions("-DCALL_LOGS_STORAGE_ENABLED")
endif()
endif()
if(ENABLE_DEBUG_LOGS)
add_definitions("-DDEBUG")
if(INTL_FOUND)
set(HAVE_INTL 1)
include_directories(${INTL_INCLUDE_DIRS})
endif()
if(MSVC)
include_directories(${MSVC_INCLUDE_DIR})
endif()
if(INTL_FOUND)
set(HAVE_INTL 1)
include_directories(${INTL_INCLUDE_DIRECTORIES})
endif()
add_definitions("-DIN_LINPHONE")
if(ENABLE_DEBUG_LOGS)
add_definitions("-DDEBUG")
endif()
if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
......@@ -234,6 +233,13 @@ if(ENABLE_VIDEO)
endif()
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
set(EXPORT_TARGETS_NAME "LinphoneBuilder")
else()
set(EXPORT_TARGETS_NAME "Linphone")
endif()
add_subdirectory(coreapi)
add_subdirectory(share)
if(ENABLE_CONSOLE_UI)
......@@ -258,9 +264,8 @@ write_basic_package_version_file(
VERSION ${LINPHONE_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT LinphoneTargets
export(EXPORT ${EXPORT_TARGETS_NAME}Targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/LinphoneTargets.cmake"
NAMESPACE BelledonneCommunications::
)
configure_file(cmake/LinphoneConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/LinphoneConfig.cmake"
......@@ -268,9 +273,8 @@ configure_file(cmake/LinphoneConfig.cmake.in
)
set(ConfigPackageLocation lib/cmake/Linphone)
install(EXPORT LinphoneTargets
install(EXPORT ${EXPORT_TARGETS_NAME}Targets
FILE LinphoneTargets.cmake
NAMESPACE BelledonneCommunications::
DESTINATION ${ConfigPackageLocation}
)
install(FILES
......
......@@ -32,7 +32,7 @@ In order to enable generation of bundle for older MacOS version, it is recommend
Install `GTK`. It is recommended to use the `quartz` backend for better integration.
sudo port install gtk2 +quartz +no_x11
sudo port install gtk-osx-application +no_python
sudo port install gtk-osx-application-gtk2 +no_python
sudo port install hicolor-icon-theme
#### Using HomeBrew
......@@ -78,7 +78,7 @@ The next pieces need to be compiled manually.
* Install libvpx (Must be manualy build because the macport recipe does not support 'macosx_deployment_target')
git clone https://chromium.googlesource.com/webm/libvpx -b v1.3.0
git clone https://chromium.googlesource.com/webm/libvpx -b v1.4.0
cd libvpx
./configure --prefix=/opt/local \
--target=x86_64-darwin10-gcc \
......@@ -143,15 +143,12 @@ The next pieces need to be compiled manually.
### Generate portable bundle
If you want to generate a portable bundle, then install `gtk-mac-bundler`:
If you want to generate a portable bundle, then install `gtk-mac-bundler` linphone fork:
git clone https://github.com/jralls/gtk-mac-bundler.git
cd gtk-mac-bundler
git checkout 6e2ed855aaeae43c29436c342ae83568573b5636
git clone git://git.linphone.org/gtk-mac-bundler.git
cd gtk-mac-bundler
make install
export PATH=$PATH:~/.local/bin
# make this dummy charset.alias file for the bundler to be happy:
sudo touch /opt/local/lib/charset.alias
export PATH=$PATH:~/.local/bin
# set writing right for owner on the libssl and libcrypto libraries in order gtk-mac-bundler
# be able to rewrite their rpath
sudo chmod u+w /opt/local/lib/libssl.1.0.0.dylib /opt/local/lib/libcrypto.1.0.0.dylib
......@@ -180,11 +177,11 @@ The resulting bundle is located in Linphone build directory, together with a zip
* For a better appearance, you can install `gtk-quartz-engine` (a GTK theme) that makes GTK application more similar to other Mac applications (but not perfect).
sudo port install gnome-common
git clone https://github.com/jralls/gtk-quartz-engine.git
cd gtk-quartz-engine
./autogen.sh
./configure --prefix=/opt/local CFLAGS="$CFLAGS -Wno-error" && make
sudo make install
git clone https://github.com/jralls/gtk-quartz-engine.git
cd gtk-quartz-engine
./autogen.sh
./configure --prefix=/opt/local CFLAGS="$CFLAGS -Wno-error" && make
sudo make install
Generate a new bundle to have it included.
......
......@@ -41,7 +41,7 @@ if(ZLIB_INCLUDE_DIRS)
endif()
if(ENABLE_STATIC)
if(IOS)
if(IOS OR QNX)
set(_ZLIB_STATIC_NAMES z)
else()
set(_ZLIB_STATIC_NAMES zstatic zlibstatic zlibstaticd)
......
......@@ -41,7 +41,7 @@ endif()
get_filename_component(LINPHONE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(LINPHONE_INCLUDE_DIRS "${LINPHONE_CMAKE_DIR}/../../../include")
set(LINPHONE_LIBRARIES BelledonneCommunications::linphone)
set(LINPHONE_LIBRARIES linphone)
set(LINPHONE_LDFLAGS @LINK_FLAGS@)
list(APPEND LINPHONE_INCLUDE_DIRS ${MEDIASTREAMER2_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS})
list(APPEND LINPHONE_LIBRARIES ${MEDIASTREAMER2_LIBRARIES} ${BELLESIP_LIBRARIES})
......
......@@ -43,4 +43,5 @@
#cmakedefine HAVE_CU_GET_SUITE 1
#cmakedefine HAVE_CU_CURSES 1
#cmakedefine HAVE_LIBUDEV_H 0
#cmakedefine HAVE_LIME
#cmakedefine ENABLE_NLS 1
......@@ -20,13 +20,13 @@
#
############################################################################
if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
find_library(LIBGCC NAMES gcc)
find_library(LIBMINGWEX NAMES mingwex)
endif()
if(NOT WIN32)
find_package(Iconv)
find_package(Iconv QUIET)
endif()
......@@ -69,6 +69,7 @@ set(SOURCE_FILES
linphonecore.c
linphone_tunnel_config.c
localplayer.c
lpc2xml.c
lpconfig.c
lpconfig.h
lsd.c
......@@ -120,13 +121,11 @@ else()
list(APPEND SOURCE_FILES linphone_tunnel_stubs.c)
endif()
set(GENERATED_SOURCE_FILES
${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h
)
set_source_files_properties(${GENERATED_SOURCE_FILES} PROPERTIES GENERATED TRUE)
find_package(Git)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h
COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DWORK_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake)
add_custom_target(liblinphone-git-version
COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DWORK_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h"
)
add_definitions(
-DUSE_BELLESIP
......@@ -150,10 +149,10 @@ endif()
if(ENABLE_TUNNEL)
list(APPEND LIBS ${TUNNEL_LIBRARIES})
endif()
if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
list(APPEND LIBS ${LIBGCC} ${LIBMINGWEX})
endif()
if(WIN32 AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
list(APPEND LIBS shlwapi)
endif()
if(INTL_FOUND)
......@@ -161,10 +160,10 @@ if(INTL_FOUND)
endif()
if(ENABLE_STATIC)
add_library(linphone STATIC ${SOURCE_FILES} ${GENERATED_SOURCE_FILES})
add_library(linphone STATIC ${SOURCE_FILES})
target_link_libraries(linphone ${LIBS})
else()
add_library(linphone SHARED ${SOURCE_FILES} ${GENERATED_SOURCE_FILES})
add_library(linphone SHARED ${SOURCE_FILES})
set_target_properties(linphone PROPERTIES VERSION ${LINPHONE_SO_VERSION} LINKER_LANGUAGE CXX)
target_link_libraries(linphone ${LIBS})
if(MSVC)
......@@ -176,7 +175,8 @@ else()
endif()
endif()
endif()
if(WIN32 AND "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
add_dependencies(linphone liblinphone-git-version)
if(WIN32 AND CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
set_target_properties(linphone PROPERTIES PREFIX "lib")
endif()
if(ICONV_FOUND)
......@@ -188,7 +188,7 @@ if(ICONV_FOUND)
endif()
endif()
install(TARGETS linphone EXPORT LinphoneTargets
install(TARGETS linphone EXPORT ${EXPORT_TARGETS_NAME}Targets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
......
......@@ -173,7 +173,7 @@ static bool_t is_matching_regex(const char *entry, const char* regex) {
char err_msg[256];
int res;
res = regcomp(&regex_pattern, regex, REG_EXTENDED | REG_NOSUB);
if(res != REG_NOERROR) {
if(res != 0) {
regerror(res, &regex_pattern, err_msg, sizeof(err_msg));
ms_error("Could not compile regex '%s: %s", regex, err_msg);
return FALSE;
......
......@@ -142,8 +142,8 @@ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, in
{
char key[50];
bool_t store_ha1_passwd = lp_config_get_int(config, "sip", "store_ha1_passwd", 1);
sprintf(key,"auth_info_%i",pos);
lp_config_clean_section(config,key);
......@@ -275,18 +275,10 @@ const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const ch
if (ai==NULL){
ai=find_auth_info(lc,username,NULL,NULL, ignore_realm);
}
/*if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", ai->username, ai->realm);*/
if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", ai->username ? ai->username : "", ai->realm ? ai->realm : "");
return ai;
}
/**
* Find authentication info matching realm, username, domain criteria.
* First of all, (realm,username) pair are searched. If multiple results (which should not happen because realm are supposed to be unique), then domain is added to the search.
* @param lc the LinphoneCore
* @param realm the authentication 'realm' (optional)
* @param username the SIP username to be authenticated (mandatory)
* @param domain the SIP domain name (optional)
* @return a #LinphoneAuthInfo
**/
const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain){
return _linphone_core_find_auth_info(lc, realm, username, domain, TRUE);
}
......@@ -295,9 +287,9 @@ const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const cha
void linphone_core_write_auth_info(LinphoneCore *lc, LinphoneAuthInfo *ai){
int i;
MSList *elem = lc->auth_info;
if (!lc->sip_conf.save_auth_info) return;
for (i=0; elem != NULL; elem = elem->next, i++){
if (ai == elem->data){
linphone_auth_info_write_config(lc->config, ai, i);
......
......@@ -357,6 +357,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
belle_sip_server_transaction_t *server_transaction=belle_sip_transaction_terminated_event_get_server_transaction(event);
belle_sip_request_t* req;
belle_sip_response_t* resp;
int code = 0;
bool_t release_call=FALSE;
if (client_transaction) {
......@@ -366,12 +367,19 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction));
resp=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(server_transaction));
}
if (op->state ==SalOpStateTerminating
if (resp) code = belle_sip_response_get_status_code(resp);
if (op->state == SalOpStateTerminating
&& strcmp("BYE",belle_sip_request_get_method(req))==0
&& (!resp || (belle_sip_response_get_status_code(resp) !=401
&& belle_sip_response_get_status_code(resp) !=407))
&& (!resp || (belle_sip_response_get_status_code(resp) != 401
&& belle_sip_response_get_status_code(resp) != 407))
&& op->dialog==NULL) {
release_call=TRUE;
}else if (op->state == SalOpStateEarly && code < 200){
/*call terminated early*/
sal_error_info_set(&op->error_info,SalReasonIOError,503,"I/O error",NULL);
op->base.root->callbacks.call_failure(op);
release_call=TRUE;
}
if (server_transaction){
if (op->pending_server_trans==server_transaction){
......@@ -546,10 +554,9 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
drop_op = TRUE;
}
break;
} /* else same behavior as for EARLY state*/
} /* else same behavior as for EARLY state, thus NO BREAK*/
}
case BELLE_SIP_DIALOG_EARLY: {
//hmm probably a cancel
if (strcmp("CANCEL",method)==0) {
if(belle_sip_request_event_get_server_transaction(event)) {
/*first answer 200 ok to cancel*/
......@@ -864,6 +871,9 @@ int sal_call_accept(SalOp*h){
belle_sip_object_unref(h->pending_update_server_trans);
h->pending_update_server_trans=NULL;
}
if (h->state == SalOpStateEarly){
h->state = SalOpStateActive;
}
return 0;
}
......
......@@ -129,8 +129,7 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
if (!op->dialog) {
if (strcmp(method,"SUBSCRIBE")==0){
op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction));
belle_sip_dialog_set_application_data(op->dialog,op);
sal_op_ref(op);
belle_sip_dialog_set_application_data(op->dialog, sal_op_ref(op));
ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
}else{ /*this is a NOTIFY*/
handle_notify(op,req,eventname,&body);
......
......@@ -72,7 +72,7 @@ void sal_op_authenticate(SalOp *op, const SalAuthInfo *info){
/*Registration authenticate is just about registering again*/
sal_register_refresh(op,-1);
}else {
/*for sure auth info will be accesible from the provider*/
/*for sure auth info will be accessible from the provider*/
sal_process_authentication(op);
}
return ;
......@@ -814,6 +814,11 @@ void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) {
void sal_op_cnx_ip_to_0000_if_sendonly_enable(SalOp *op,bool_t yesno) {
op->cnx_ip_to_0000_if_sendonly_enabled = yesno;
}
bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *op) {
return op->cnx_ip_to_0000_if_sendonly_enabled;
}
bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2){
return op1->base.call_id && op2->base.call_id && strcmp(op1->base.call_id, op2->base.call_id) == 0;
}
......@@ -47,42 +47,39 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo
}
static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
ms_error("presence_process_io_error not implemented yet");
/*ms_error("presence_process_io_error not implemented yet");*/
}
static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
SalOp* op= (SalOp*)ctx;
if (op->dialog) {
sal_op_unref(op);
op->dialog=NULL;
if (belle_sip_dialog_is_server(op->dialog)){
ms_message("Incoming subscribtion from [%s] terminated",sal_op_get_from(op));
op->base.root->callbacks.subscribe_presence_closed(op, sal_op_get_from(op));
}
set_or_update_dialog(op, NULL);
}
}
static void presence_refresher_listener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase){
SalOp* op = (SalOp*)user_pointer;
switch(status_code){
case 481: {
ms_message("The server or remote ua lost the SUBSCRIBE dialog context. Let's restart a new one.");
belle_sip_refresher_stop(op->refresher);
if (op->dialog) { /*delete previous dialog if any*/
belle_sip_dialog_set_application_data(op->dialog,NULL);
belle_sip_object_unref(op->dialog);
op->dialog=NULL;
}
if (sal_op_get_contact_address(op)) {
/*contact is also probably not good*/
SalAddress* contact=sal_address_clone(sal_op_get_contact_address(op));
sal_address_set_port(contact,-1);
sal_address_set_domain(contact,NULL);
sal_op_set_contact_address(op,contact);
sal_address_destroy(contact);
}
if (status_code >= 300) {
ms_message("The SUBSCRIBE dialog no longer works. Let's restart a new one.");
belle_sip_refresher_stop(op->refresher);
if (op->dialog) { /*delete previous dialog if any*/
set_or_update_dialog(op, NULL);
}
sal_subscribe_presence(op,NULL,NULL,-1);
break;
if (sal_op_get_contact_address(op)) {
/*contact is also probably not good*/
SalAddress* contact=sal_address_clone(sal_op_get_contact_address(op));
sal_address_set_port(contact,-1);
sal_address_set_domain(contact,NULL);
sal_op_set_contact_address(op,contact);
sal_address_destroy(contact);
}
/*send a new SUBSCRIBE, that will attempt to establish a new dialog*/
sal_subscribe_presence(op,NULL,NULL,-1);
}
}
......@@ -99,9 +96,11 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
sal_op_set_error_info_from_response(op,response);
if (code>=300) {
ms_message("subscription to [%s] rejected",sal_op_get_to(op));
op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
return;
if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){
ms_message("subscription to [%s] rejected",sal_op_get_to(op));
op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
return;
}
}
set_or_update_dialog(op_base,belle_sip_response_event_get_dialog(event));
if (!op->dialog) {
......@@ -144,11 +143,21 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
}
/* no break */
}
}
static void presence_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
ms_error("presence_process_timeout not implemented yet");
SalOp* op = (SalOp*)user_ctx;
belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event);
belle_sip_request_t* request;
if (!client_transaction) return;
request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){
ms_message("subscription to [%s] timeout",sal_op_get_to(op));
op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
}
}
static void presence_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
......@@ -177,15 +186,19 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req
return result;
}
static void handle_notify(SalOp *op, belle_sip_request_t *req){
static void handle_notify(SalOp *op, belle_sip_request_t *req, belle_sip_dialog_t *dialog){
belle_sip_response_t* resp=NULL;
belle_sip_server_transaction_t* server_transaction=op->pending_server_trans;
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
SalSubscribeStatus sub_state;
if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) {
SalPresenceModel *presence_model = NULL;
const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
if (op->dialog !=NULL && dialog != op->dialog){
ms_warning("Receiving a NOTIFY from a dialog we haven't stored (op->dialog=%p dialog=%p)", op->dialog, dialog);
}
if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) {
sub_state=SalSubscribeTerminated;
ms_message("Outgoing subscription terminated by remote [%s]",sal_op_get_to(op));
......@@ -212,7 +225,6 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
belle_sip_dialog_state_t dialog_state;
belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
belle_sip_response_t* resp;
const char *method=belle_sip_request_get_method(req);
......@@ -223,13 +235,12 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
if (!op->dialog) {
if (strcmp(method,"SUBSCRIBE")==0){
op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction));
belle_sip_dialog_set_application_data(op->dialog,op);
sal_op_ref(op);
belle_sip_dialog_t *dialog = belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction));
set_or_update_dialog(op, dialog);
ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
}else{ /* this is a NOTIFY */
ms_message("Receiving out of dialog notify");
handle_notify(op,req);
handle_notify(op, req, belle_sip_request_event_get_dialog(event));
return;
}
}
......@@ -245,16 +256,13 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
case BELLE_SIP_DIALOG_CONFIRMED:
if (strcmp("NOTIFY",method)==0) {
handle_notify(op,req);
handle_notify(op, req, belle_sip_request_event_get_dialog(event));
} else if (strcmp("SUBSCRIBE",method)==0) {
/*either a refresh or an unsubscribe*/
if (expires && belle_sip_header_expires_get_expires(expires)>0) {
op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op));
} else if(expires) {
ms_message("Unsubscribe received from [%s]",sal_op_get_from(op));
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
}
/*either a refresh or an unsubscribe.
If it is a refresh there is nothing to notify to the app. If it is an unSUBSCRIBE, then the dialog
will be terminated shortly, and this will be notified to the app through the dialog_terminated callback.*/
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
}
break;
default:
......@@ -330,8 +338,8 @@ static int sal_op_check_dialog_state(SalOp *op) {
return -1;
} else
return 0;
}
int sal_notify_presence(SalOp *op, SalPresenceModel *presence){
belle_sip_request_t* notify=NULL;
if (sal_op_check_dialog_state(op)) {
......
......@@ -331,7 +331,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
}
}
if ((rtp_port != 0) && ((stream->proto == SalProtoRtpAvpf) || (stream->proto == SalProtoRtpSavpf))) {