diff --git a/CMakeLists.txt b/CMakeLists.txt
index 723b0de75..d0f53f1ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,6 +54,7 @@ option(ENABLE_TOOLS "Turn on or off compilation of tools." YES)
option(ENABLE_TUNNEL "Turn on compilation of tunnel support." NO)
option(ENABLE_TUTORIALS "Enable compilation of tutorials." YES)
option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES)
+option(ENABLE_UPDATE_CHECK "Enable update check." NO)
option(ENABLE_VIDEO "Build with video support." YES)
cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO)
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
diff --git a/build/osx/Info.plist.in b/build/osx/Info.plist.in
new file mode 100644
index 000000000..208198e39
--- /dev/null
+++ b/build/osx/Info.plist.in
@@ -0,0 +1,43 @@
+
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ linphone
+ CFBundleGetInfoString
+ ${MACOSX_BUNDLE_INFO_STRING}
+ CFBundleIconFile
+ ${MACOSX_BUNDLE_ICON_FILE}
+ CFBundleIdentifier
+ ${MACOSX_FRAMEWORK_IDENTIFIER}
+ LSMinimumSystemVersion
+ ${MIN_OS}
+ MinimumOSVersion
+ ${MIN_OS}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleLongVersionString
+ ${MACOSX_BUNDLE_LONG_VERSION_STRING}
+ CFBundleName
+ ${MACOSX_BUNDLE_BUNDLE_NAME}
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ ${LINPHONE_VERSION}
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ ${LINPHONE_VERSION}
+ CSResourcesFileMapped
+
+ NSHumanReadableCopyright
+ ${MACOSX_BUNDLE_COPYRIGHT}
+ NSPrincipalClass
+ NSApplication
+ NSHighResolutionCapable
+ True
+
+
\ No newline at end of file
diff --git a/config.h.cmake b/config.h.cmake
index fe8fd9769..5de3f36a3 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -47,3 +47,4 @@
#cmakedefine HAVE_LIBUDEV_H 0
#cmakedefine HAVE_LIME
#cmakedefine ENABLE_NLS 1
+#cmakedefine ENABLE_UPDATE_CHECK 1
diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt
index 9a88be283..c60c54ccb 100644
--- a/coreapi/CMakeLists.txt
+++ b/coreapi/CMakeLists.txt
@@ -224,9 +224,16 @@ endif()
if(ENABLE_SHARED)
add_library(linphone SHARED ${LINPHONE_HEADER_FILES} ${LINPHONE_PRIVATE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC})
if(IOS)
+ if(IOS)
+ set(MIN_OS ${LINPHONE_IOS_DEPLOYMENT_TARGET})
+ else()
+ set(MIN_OS ${CMAKE_OSX_DEPLOYMENT_TARGET})
+ endif()
+ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/build/osx/")
set_target_properties(linphone PROPERTIES
FRAMEWORK TRUE
- MACOSX_FRAMEWORK_IDENTIFIER com.belledonne-communications.linphone
+ MACOSX_FRAMEWORK_IDENTIFIER org.linphone.linphone
+ MACOSX_FRAMEWORK_INFO_PLIST Info.plist.in
PUBLIC_HEADER "${LINPHONE_HEADER_FILES}"
)
endif()
diff --git a/coreapi/address.c b/coreapi/address.c
index 35fbe2808..696ff0ba8 100644
--- a/coreapi/address.c
+++ b/coreapi/address.c
@@ -178,6 +178,10 @@ void linphone_address_set_header(LinphoneAddress *addr, const char *header_name,
sal_address_set_header(addr,header_name,header_value);
}
+const char *linphone_address_get_header(const LinphoneAddress *addr, const char *name){
+ return sal_address_get_header(addr,name);
+}
+
bool_t linphone_address_has_param(const LinphoneAddress *addr, const char *name) {
return sal_address_has_param(addr, name);
}
diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c
index 6a9afe9d5..dbeb9b8e0 100644
--- a/coreapi/bellesip_sal/sal_address_impl.c
+++ b/coreapi/bellesip_sal/sal_address_impl.c
@@ -236,6 +236,11 @@ void sal_address_set_header(SalAddress *addr, const char *header_name, const cha
belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)),header_name, header_value);
}
+
+const char* sal_address_get_header(const SalAddress *addr, const char *name){
+ return belle_sip_uri_get_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)),name);
+}
+
void sal_address_set_transport(SalAddress* addr,SalTransport transport){
if (!sal_address_is_secure(addr)){
SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport));
diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h
index 9ed481d11..6c290ff33 100644
--- a/coreapi/bellesip_sal/sal_impl.h
+++ b/coreapi/bellesip_sal/sal_impl.h
@@ -150,7 +150,7 @@ belle_sip_header_contact_t* sal_op_create_contact(SalOp *op) ;
bool_t _sal_compute_sal_errors(belle_sip_response_t* response, SalReason* sal_reason, char* reason, size_t reason_size);
SalReason _sal_reason_from_sip_code(int code);
-
+void sal_op_set_reason_error_info(SalOp *op, belle_sip_message_t *msg);
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response);
/*presence*/
void sal_op_presence_fill_cbs(SalOp*op);
diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c
index df06c1e8e..c89f38289 100644
--- a/coreapi/bellesip_sal/sal_op_call.c
+++ b/coreapi/bellesip_sal/sal_op_call.c
@@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sal_impl.h"
#include "offeranswer.h"
+#include
+
static int extract_sdp(SalOp* op,belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error);
/*used for calls terminated before creation of a dialog*/
@@ -149,10 +151,10 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event
if (op->state == SalOpStateTerminated) return;
if (op->pending_client_trans && (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_INIT)) {
-
+
sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "IO error", NULL);
op->base.root->callbacks.call_failure(op);
-
+
if (!op->dialog || belle_sip_dialog_get_state(op->dialog) != BELLE_SIP_DIALOG_CONFIRMED){
/* Call terminated very very early, before INVITE is even sent, probably DNS resolution timeout. */
op->state = SalOpStateTerminating;
@@ -215,31 +217,12 @@ static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
if (op->base.local_media) sdp_process(op);
}
-void sal_call_cancel_invite(SalOp* op) {
- belle_sip_request_t* cancel;
- ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
- cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
- if (cancel){
- sal_op_send_request(op,cancel);
- }else if (op->dialog){
- belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);;
- /*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
- * because already terminated*/
- switch(state){
- case BELLE_SIP_DIALOG_EARLY:
- case BELLE_SIP_DIALOG_NULL:
- /*force kill the dialog*/
- ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
- belle_sip_dialog_delete(op->dialog);
- break;
- default:
- break;
- }
- }
+void sal_call_cancel_invite(SalOp *op) {
+ sal_call_cancel_invite_with_info(op,NULL);
}
-static void cancelling_invite(SalOp *op) {
- sal_call_cancel_invite(op);
+static void cancelling_invite(SalOp *op, const SalErrorInfo *info) {
+ sal_call_cancel_invite_with_info(op, info);
op->state=SalOpStateTerminating;
}
@@ -282,7 +265,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
/*it wasn't sent */
if (code<200) {
- cancelling_invite(op);
+ cancelling_invite(op, NULL);
}else{
/* no need to send the INVITE because the UAS rejected the INVITE*/
if (op->dialog==NULL) call_set_released(op);
@@ -412,7 +395,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
resp=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(server_transaction));
}
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
@@ -439,12 +422,14 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
if (release_call) call_set_released(op);
}
-static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, belle_sip_request_t* request,int status_code) {
+static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request) {
belle_sip_response_t* resp;
+ belle_sip_request_t* server_req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction));
op->state = SalOpStateTerminating;
- op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
- resp=sal_op_create_response_from_request(op,request,status_code);
+ sal_op_set_reason_error_info(op, BELLE_SIP_MESSAGE(cancel_request ? cancel_request : server_req));
+ resp=sal_op_create_response_from_request(op,server_req,status_code);
belle_sip_server_transaction_send_response(server_transaction,resp);
+ op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
}
static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request) {
@@ -611,7 +596,7 @@ 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, thus NO BREAK*/
+ }BCTBX_NO_BREAK; /* else same behavior as for EARLY state, thus NO BREAK*/
}
case BELLE_SIP_DIALOG_EARLY: {
if (strcmp("CANCEL",method)==0) {
@@ -620,11 +605,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_server_transaction_send_response(server_transaction
,sal_op_create_response_from_request(op,req,200));
/*terminate invite transaction*/
- call_terminated(op
- ,op->pending_server_trans
- ,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),487);
-
-
+ call_terminated(op,op->pending_server_trans,487,req);
} else {
/*call leg does not exist*/
belle_sip_server_transaction_send_response(server_transaction
@@ -646,7 +627,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
case BELLE_SIP_DIALOG_CONFIRMED:
/*great ACK received*/
if (strcmp("ACK",method)==0) {
- if (!op->pending_client_trans ||
+ if (!op->pending_client_trans ||
!belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state((belle_sip_transaction_t*)op->pending_client_trans))){
if (op->sdp_offering){
SalReason reason;
@@ -668,10 +649,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
ms_message("Ignored received ack since a new client transaction has been started since.");
}
} else if(strcmp("BYE",method)==0) {
- resp=sal_op_create_response_from_request(op,req,200);
- belle_sip_server_transaction_send_response(server_transaction,resp);
- op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
- op->state=SalOpStateTerminating;
+ call_terminated(op,server_transaction,200,req);
/*call end not notified by dialog deletion because transaction can end before dialog*/
} else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) {
if (is_update && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) {
@@ -957,6 +935,33 @@ static belle_sip_header_reason_t *sal_call_make_reason_header( const SalErrorInf
return NULL;
}
+void sal_call_cancel_invite_with_info(SalOp* op, const SalErrorInfo *info) {
+ belle_sip_request_t* cancel;
+ ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
+ cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
+ if (cancel){
+ if (info != NULL){
+ belle_sip_header_reason_t* reason = sal_call_make_reason_header(info);
+ belle_sip_message_add_header(BELLE_SIP_MESSAGE(cancel),BELLE_SIP_HEADER(reason));
+ }
+ sal_op_send_request(op,cancel);
+ }else if (op->dialog){
+ belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);;
+ /*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
+ * because already terminated*/
+ switch(state){
+ case BELLE_SIP_DIALOG_EARLY:
+ case BELLE_SIP_DIALOG_NULL:
+ /*force kill the dialog*/
+ ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
+ belle_sip_dialog_delete(op->dialog);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*optional*/){
belle_sip_response_t* response;
belle_sip_header_contact_t* contact=NULL;
@@ -990,7 +995,7 @@ int sal_call_decline_with_error_info(SalOp *op, const SalErrorInfo *info, const
belle_sip_header_contact_t* contact=NULL;
int status = info->protocol_code;
belle_sip_transaction_t *trans;
-
+
if (info->reason==SalReasonRedirect){
if (redirection!=NULL) {
if (strstr(redirection,"sip:")!=0) status=302;
@@ -1093,17 +1098,20 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){
int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){
SalErrorInfo sei = { 0 };
const SalErrorInfo *p_sei;
- if (info == NULL){
+ belle_sip_dialog_state_t dialog_state = op->dialog ? belle_sip_dialog_get_state(op->dialog) : BELLE_SIP_DIALOG_NULL;
+ int ret = 0;
+
+ if (info == NULL && dialog_state != BELLE_SIP_DIALOG_CONFIRMED && op->dir == SalOpDirIncoming){
+ /*the purpose of this line is to set a default SalErrorInfo for declining an incoming call (not yet established of course) */
sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL);
p_sei = &sei;
} else{
p_sei = info;
-
}
- belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL;
if (op->state==SalOpStateTerminating || op->state==SalOpStateTerminated) {
ms_error("Cannot terminate op [%p] in state [%s]",op,sal_op_state_to_string(op->state));
- return -1;
+ ret = -1;
+ goto end;
}
switch(dialog_state) {
case BELLE_SIP_DIALOG_CONFIRMED: {
@@ -1123,7 +1131,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){
op->state=SalOpStateTerminated;
} else if (op->pending_client_trans){
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){
- cancelling_invite(op);
+ cancelling_invite(op, p_sei);
}else{
/* Case where the CANCEL cannot be sent because no provisional response was received so far.
* The Op must be kept for the time of the transaction in case a response is received later.
@@ -1139,16 +1147,19 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){
sal_call_decline_with_error_info(op, p_sei,NULL);
op->state=SalOpStateTerminated;
} else {
- cancelling_invite(op);
+ cancelling_invite(op, p_sei);
}
break;
}
default: {
ms_error("sal_call_terminate not implemented yet for dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
- return -1;
+ ret = -1;
+ goto end;
}
}
- return 0;
+end:
+ sal_error_info_reset(&sei);
+ return ret;
}
diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c
index 65911275d..0b4566546 100644
--- a/coreapi/callbacks.c
+++ b/coreapi/callbacks.c
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "private.h"
#include "mediastreamer2/mediastream.h"
#include "linphone/lpconfig.h"
+#include
// stat
#ifndef _WIN32
@@ -145,6 +146,7 @@ void linphone_call_update_streams(LinphoneCall *call, SalMediaDescription *new_m
/* We already started media: check if we really need to restart it */
if (oldmd) {
md_changed = media_parameters_changed(call, oldmd, new_md);
+ /*might not be mandatory to restart stream for each ice restart as it leads bad user experience, specially in video. See 0002495 for better background on this*/
if ((md_changed & ( SAL_MEDIA_DESCRIPTION_CODEC_CHANGED
|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED
|SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED
@@ -255,7 +257,7 @@ static LinphoneCall * look_for_broken_call_to_replace(SalOp *h, LinphoneCore *lc
}
it = bctbx_list_next(it);
}
-
+
return NULL;
}
@@ -277,7 +279,7 @@ static void call_received(SalOp *h){
linphone_call_replace_op(replaced_call, h);
return;
}
-
+
p_asserted_id = sal_custom_header_find(sal_op_get_recv_custom_header(h),"P-Asserted-Identity");
/*in some situation, better to trust the network rather than the UAC*/
if (lp_config_get_int(lc->config,"sip","call_logs_use_asserted_id_instead_of_from",0)) {
@@ -332,7 +334,7 @@ static void call_received(SalOp *h){
sal_op_release(h);
return;
}
-
+
if (sal_op_get_privacy(h) == SalPrivacyNone) {
from_address_to_search_if_me=linphone_address_clone(from_addr);
@@ -569,10 +571,10 @@ static void process_call_accepted(LinphoneCore *lc, LinphoneCall *call, SalOp *o
switch (call->state){
case LinphoneCallResuming:
linphone_core_notify_display_status(lc,_("Call resumed."));
- /*intentionally no break*/
+ BCTBX_NO_BREAK; /*intentionally no break*/
case LinphoneCallConnected:
if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
- /*intentionally no break*/
+ BCTBX_NO_BREAK; /*intentionally no break*/
case LinphoneCallUpdating:
case LinphoneCallUpdatedByRemote:
if (!sal_media_description_has_dir(call->localdesc, SalStreamInactive) &&
@@ -741,7 +743,7 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t
case LinphoneCallResuming:
sal_error_info_set(&sei,SalReasonInternalError, "SIP", 0, NULL, NULL);
sal_call_decline_with_error_info(call->op, &sei,NULL);
- /*no break*/
+ BCTBX_NO_BREAK; /*no break*/
case LinphoneCallIdle:
case LinphoneCallOutgoingInit:
case LinphoneCallEnd:
@@ -764,7 +766,7 @@ static void call_updating(SalOp *op, bool_t is_update){
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
SalMediaDescription *rmd=sal_call_get_remote_media_description(op);
SalErrorInfo sei = {0};
-
+
if (!call) {
ms_error("call_updating(): call doesn't exist anymore");
return ;
@@ -849,9 +851,11 @@ static void call_terminated(SalOp *op, const char *from){
break;
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
- linphone_error_info_set(call->ei,NULL, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL);
- call->non_op_error = TRUE;
- break;
+ if(!sal_op_get_reason_error_info(op)->protocol || strcmp(sal_op_get_reason_error_info(op)->protocol, "") == 0) {
+ linphone_error_info_set(call->ei,NULL, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL);
+ call->non_op_error = TRUE;
+ }
+ break;
default:
break;
}
@@ -903,12 +907,12 @@ static void call_failure(SalOp *op){
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
bool_t stop_ringing = TRUE;
bctbx_list_t *calls = lc->calls;
-
+
if (call==NULL){
ms_warning("Call faillure reported on already terminated call.");
return ;
}
-
+
referer=call->referer;
linphone_core_notify_show_interface(lc);
@@ -1136,10 +1140,10 @@ static void register_failure(SalOp *op){
} else {
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details);
}
- if (cfg->long_term_event){
+ if (cfg->presence_publish_event){
/*prevent publish to be sent now until registration gets successful*/
- linphone_event_terminate(cfg->long_term_event);
- cfg->long_term_event=NULL;
+ linphone_event_terminate(cfg->presence_publish_event);
+ cfg->presence_publish_event=NULL;
cfg->send_publish=cfg->publish;
}
}
@@ -1296,7 +1300,7 @@ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) {
fill_auth_info_with_client_certificate(lc, sai);
}
}
-
+
if (sai->realm && !ai->realm){
/*if realm was not known, then set it so that ha1 may eventually be calculated and clear text password dropped*/
linphone_auth_info_set_realm(ai, sai->realm);
@@ -1423,7 +1427,7 @@ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, SalB
if (out_of_dialog){
/*out of dialog NOTIFY do not create an implicit subscription*/
linphone_event_set_state(lev, LinphoneSubscriptionTerminated);
- }else if (st!=SalSubscribeNone){
+ }else if (st!=SalSubscribeNone){
linphone_event_set_state(lev,linphone_subscription_state_from_sal(st));
}
}
@@ -1534,5 +1538,3 @@ SalCallbacks linphone_sal_callbacks={
on_expire,
on_notify_response
};
-
-
diff --git a/coreapi/carddav.c b/coreapi/carddav.c
index 9f0ffa658..67d6184dd 100644
--- a/coreapi/carddav.c
+++ b/coreapi/carddav.c
@@ -129,6 +129,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, bctbx_li
ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url);
lf = linphone_friend_new_from_vcard(lvc);
+ linphone_vcard_unref(lvc); /*ref is now owned by friend*/
if (lf) {
local_friend = bctbx_list_find_custom(friends, (int (*)(const void*, const void*))find_matching_friend, lf);
diff --git a/coreapi/chat.c b/coreapi/chat.c
index ed8422bde..19b49caf0 100644
--- a/coreapi/chat.c
+++ b/coreapi/chat.c
@@ -661,6 +661,7 @@ LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const
const SalCustomHeader *ch;
LinphoneReason reason = LinphoneReasonNone;
int retval = -1;
+ bool_t increase_msg_count = TRUE;
addr = linphone_address_new(sal_msg->from);
linphone_address_clean(addr);
@@ -729,12 +730,14 @@ LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const
} else if (is_im_iscomposing(msg->content_type)) {
linphone_chat_room_notify_is_composing(cr, msg->message);
linphone_chat_message_set_to_be_stored(msg, FALSE);
+ increase_msg_count = FALSE;
if(lp_config_get_int(cr->lc->config, "sip", "deliver_imdn", 0) != 1) {
goto end;
}
} else if (is_imdn(msg->content_type)) {
linphone_chat_room_notify_imdn(cr, msg->message);
linphone_chat_message_set_to_be_stored(msg, FALSE);
+ increase_msg_count = FALSE;
if(lp_config_get_int(cr->lc->config, "sip", "deliver_imdn", 0) != 1) {
goto end;
}
@@ -742,17 +745,19 @@ LinphoneReason linphone_core_message_received(LinphoneCore *lc, SalOp *op, const
linphone_chat_message_set_to_be_stored(msg, TRUE);
}
- linphone_chat_room_message_received(cr, lc, msg);
-
- if(linphone_chat_message_get_to_be_stored(msg)) {
- msg->storage_id = linphone_chat_message_store(msg);
-
+ if (increase_msg_count == TRUE) {
if (cr->unread_count < 0)
cr->unread_count = 1;
else
cr->unread_count++;
}
+ linphone_chat_room_message_received(cr, lc, msg);
+
+ if(linphone_chat_message_get_to_be_stored(msg)) {
+ msg->storage_id = linphone_chat_message_store(msg);
+ }
+
end:
linphone_address_unref(addr);
if (msg != NULL) linphone_chat_message_unref(msg);
@@ -1093,7 +1098,7 @@ static void linphone_chat_room_send_is_composing_notification(LinphoneChatRoom *
msg = linphone_chat_room_create_message(cr, content);
linphone_chat_message_set_from_address(msg, from_addr);
linphone_chat_message_set_to_address(msg, to_addr);
- msg->content_type = ms_strdup("application/im-iscomposing+xml");
+ linphone_chat_message_set_content_type(msg, "application/im-iscomposing+xml");
if (imee) {
LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee);
diff --git a/coreapi/conference.cc b/coreapi/conference.cc
index 273b2dfd0..7a2af3bde 100644
--- a/coreapi/conference.cc
+++ b/coreapi/conference.cc
@@ -394,12 +394,13 @@ void LocalConference::addLocalEndpoint() {
_post_configure_audio_stream(st,m_core,FALSE);
m_localParticipantStream=st;
m_localEndpoint=ms_audio_endpoint_get_from_stream(st,FALSE);
+ ms_message("conference: adding local endpoint");
ms_audio_conference_add_member(m_conf,m_localEndpoint);
}
int LocalConference::inviteAddresses(const std::list &addresses, const LinphoneCallParams *params){
- for (auto it = addresses.begin(); it != addresses.end(); ++it){
+ for (std::list::const_iterator it = addresses.begin(); it != addresses.end(); ++it){
const LinphoneAddress *addr = *it;
LinphoneCall * call = linphone_core_get_call_by_remote_address2(m_core, addr);
if (!call){
@@ -408,6 +409,7 @@ int LocalConference::inviteAddresses(const std::list &ad
LinphoneCall *call;
/*toggle this flag so the call is immediately added to the conference upon acceptance*/
new_params->in_conference = TRUE;
+ linphone_call_params_enable_video(new_params, FALSE); /*turn off video as it is not supported for conferencing at this time*/
call = linphone_core_invite_address_with_params(m_core, addr, new_params);
if (!call){
ms_error("LocalConference::inviteAddresses(): could not invite participant");
@@ -418,6 +420,8 @@ int LocalConference::inviteAddresses(const std::list &ad
if (!call->current_params->in_conference)
addParticipant(call);
}
+ /*if the local participant is not yet created, created it and it to the conference */
+ if (!m_localEndpoint) addLocalEndpoint();
}
return 0;
}
@@ -433,7 +437,7 @@ int LocalConference::addParticipant(LinphoneCall *call) {
call->params->has_video=FALSE;
linphone_call_resume(call);
}else if (call->state==LinphoneCallStreamsRunning){
- LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call));
+ LinphoneCallParams *params = linphone_core_create_call_params(m_core, call);
params->in_conference=TRUE;
params->has_video=FALSE;
diff --git a/coreapi/dial_plan.c b/coreapi/dial_plan.c
index 758bac5a1..85c652fe8 100644
--- a/coreapi/dial_plan.c
+++ b/coreapi/dial_plan.c
@@ -158,6 +158,8 @@ static LinphoneDialPlan const dial_plans[]={
{"Mauritius" ,"MU" , "230" , 7 , "00" },
{"Mayotte Island" ,"YT" , "262" , 9 , "00" },
{"Mexico" ,"MX" , "52" , 10 , "00" },
+ /*The following is a pseudo dial plan for Mexican mobile phones. See https://en.wikipedia.org/wiki/Telephone_numbers_in_Mexico*/
+ {"Mexico" ,"MX" , "521" , 10 , "00" },
{"Micronesia" ,"FM" , "691" , 7 , "011" },
{"Moldova" ,"MD" , "373" , 8 , "00" },
{"Monaco" ,"MC" , "377" , 8 , "00" },
@@ -172,7 +174,7 @@ static LinphoneDialPlan const dial_plans[]={
{"Nepal" ,"NP" , "43" , 10 , "00" },
{"Netherlands" ,"NL" , "31" , 9 , "00" },
{"New Caledonia" ,"NC" , "687" , 6 , "00" },
- {"New Zealand" ,"NZ" , "64" , 10 , "00" },
+ {"New Zealand" ,"NZ" , "64" , 8 , "00" },
{"Nicaragua" ,"NI" , "505" , 8 , "00" },
{"Niger" ,"NE" , "227" , 8 , "00" },
{"Nigeria" ,"NG" , "234" , 10 , "009" },
@@ -261,7 +263,7 @@ int linphone_dial_plan_lookup_ccc_from_e164(const char* e164) {
LinphoneDialPlan* elected_dial_plan=NULL;
unsigned int found;
unsigned int i=0;
-
+
if (e164[0]!='+') {
return -1;/*not an e164 number*/
}
@@ -300,7 +302,7 @@ const LinphoneDialPlan* linphone_dial_plan_by_ccc_as_int(int ccc) {
int i;
char ccc_as_char[16] = {0};
snprintf(ccc_as_char,sizeof(ccc_as_char)-1,"%i",ccc);
-
+
for(i=0;dial_plans[i].country!=NULL;++i){
if (strcmp(ccc_as_char,dial_plans[i].ccc)==0){
return &dial_plans[i];
diff --git a/coreapi/ec-calibrator.c b/coreapi/ec-calibrator.c
index c9101745b..dc8e66d15 100644
--- a/coreapi/ec-calibrator.c
+++ b/coreapi/ec-calibrator.c
@@ -44,8 +44,8 @@ static void ecc_init_filters(EcCalibrator *ecc){
ecc->read_resampler=ms_factory_create_filter(ecc->factory, MS_RESAMPLE_ID);
ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_SAMPLE_RATE,&rate);
ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&ecc->rate);
- ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_NCHANNELS,&ecc_channels);
- ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&channels);
+ ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_NCHANNELS,&channels);
+ ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&ecc_channels);
ecc->det=ms_factory_create_filter(ecc->factory, MS_TONE_DETECTOR_ID);
diff --git a/coreapi/event.c b/coreapi/event.c
index 44f6c1bf2..d5926dd96 100644
--- a/coreapi/event.c
+++ b/coreapi/event.c
@@ -272,13 +272,35 @@ LinphoneStatus linphone_event_notify(LinphoneEvent *lev, const LinphoneContent *
return sal_notify(lev->op, body_handler);
}
-LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires){
- LinphoneEvent *lev=linphone_event_new(lc,LinphoneSubscriptionInvalidDir, event,expires);
- linphone_configure_op(lc,lev->op,resource,NULL,lp_config_get_int(lc->config,"sip","publish_msg_with_contact",0));
+static LinphoneEvent *_linphone_core_create_publish(LinphoneCore *core, LinphoneProxyConfig *cfg, const LinphoneAddress *resource, const char *event, int expires){
+ LinphoneCore *lc = core;
+ LinphoneEvent *lev;
+
+ if (!lc && cfg) {
+ if (cfg->lc)
+ lc = cfg->lc;
+ else {
+ ms_error("Cannot create publish from proxy config [%p] not attached to any core",cfg);
+ return NULL;
+ }
+ }
+ if (!resource && cfg)
+ resource = linphone_proxy_config_get_identity_address(cfg);
+
+ lev = linphone_event_new(lc,LinphoneSubscriptionInvalidDir, event,expires);
+ linphone_configure_op_with_proxy(lc,lev->op,resource,NULL,lp_config_get_int(lc->config,"sip","publish_msg_with_contact",0),cfg);
sal_op_set_manual_refresher_mode(lev->op,!lp_config_get_int(lc->config,"sip","refresh_generic_publish",1));
return lev;
}
-
+LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires){
+ return _linphone_core_create_publish(lc, NULL, resource, event, expires);
+}
+LinphoneEvent *linphone_proxy_config_create_publish(LinphoneProxyConfig *cfg, const char *event, int expires) {
+
+ return _linphone_core_create_publish(NULL, cfg,NULL, event, expires);
+
+
+}
LinphoneEvent *linphone_core_create_one_shot_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event){
LinphoneEvent *lev = linphone_core_create_publish(lc, resource, event, -1);
lev->oneshot = TRUE;
diff --git a/coreapi/factory.c b/coreapi/factory.c
index 5601a620b..27e30e984 100644
--- a/coreapi/factory.c
+++ b/coreapi/factory.c
@@ -264,8 +264,12 @@ void linphone_factory_set_sound_resources_dir(LinphoneFactory *factory, const ch
const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory) {
if (factory->ring_resources_dir) return factory->ring_resources_dir;
if (factory->sound_resources_dir){
- STRING_TRANSFER(factory->cached_sound_resources_dir, bctbx_strdup_printf("%s/rings", factory->sound_resources_dir));
- return factory->cached_sound_resources_dir;
+ STRING_TRANSFER(factory->cached_ring_resources_dir, bctbx_strdup_printf("%s/rings", factory->sound_resources_dir));
+ return factory->cached_ring_resources_dir;
+ }
+ if (factory->top_resources_dir) {
+ STRING_TRANSFER(factory->cached_ring_resources_dir, bctbx_strdup_printf("%s/sounds/linphone/rings", factory->top_resources_dir));
+ return factory->cached_ring_resources_dir;
}
return PACKAGE_RING_DIR;
}
diff --git a/coreapi/friend.c b/coreapi/friend.c
index ff47cabff..30c3dd852 100644
--- a/coreapi/friend.c
+++ b/coreapi/friend.c
@@ -79,6 +79,7 @@ const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
break;
case LinphoneStatusVacation:
str=_("Vacation");
+ break;
default:
str=_("Unknown status");
}
@@ -1396,6 +1397,7 @@ static int create_friend(void *data, int argc, char **argv, char **colName) {
linphone_vcard_set_etag(vcard, argv[7]);
linphone_vcard_set_url(vcard, argv[8]);
lf = linphone_friend_new_from_vcard(vcard);
+ linphone_vcard_unref(vcard);
}
if (!lf) {
lf = linphone_friend_new();
@@ -1639,8 +1641,6 @@ bctbx_list_t* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFrie
}
iterator = bctbx_list_next(iterator);
}
-
- linphone_friend_save(lf, lc); /* required if we freshly created vcard but core was not set at this time */
}
linphone_vcard_context_set_user_data(lc->vcard_context, NULL);
diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c
index 9c4bc9eeb..7125cca85 100644
--- a/coreapi/friendlist.c
+++ b/coreapi/friendlist.c
@@ -222,10 +222,8 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
}
version = atoi(version_str);
linphone_free_xml_text_content(version_str);
- if (version < list->expected_notification_version) {
- ms_warning("rlmi+xml: Discarding received notification with version %d because %d was expected", version, list->expected_notification_version);
- linphone_friend_list_update_subscriptions(list); /* Refresh subscription to get new full state notify. */
- goto end;
+ if (version < list->expected_notification_version) { /*no longuer an error as dialog may be silently restarting by the refresher*/
+ ms_warning("rlmi+xml: Received notification with version %d expected was %d, dialog may have been reseted", version, list->expected_notification_version);
}
full_state_str = linphone_get_xml_attribute_text_content(xml_ctx, "/rlmi:list", "fullState");
@@ -1007,10 +1005,41 @@ LinphoneCore* linphone_friend_list_get_core(const LinphoneFriendList *list) {
return list->lc;
}
-LinphoneStatus linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
- bctbx_list_t *vcards = NULL;
+static LinphoneStatus linphone_friend_list_import_friends_from_vcard4(LinphoneFriendList *list, bctbx_list_t *vcards) {
bctbx_list_t *vcards_iterator = NULL;
int count = 0;
+
+ if (!linphone_core_vcard_supported()) {
+ ms_error("vCard support wasn't enabled at compilation time");
+ return -1;
+ }
+ if (!list) {
+ ms_error("Can't import into a NULL list");
+ return -1;
+ }
+
+ vcards_iterator = vcards;
+
+ while (vcards_iterator != NULL && bctbx_list_get_data(vcards_iterator) != NULL) {
+ LinphoneVcard *vcard = (LinphoneVcard *)bctbx_list_get_data(vcards_iterator);
+ LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
+ linphone_vcard_unref(vcard);
+ if (lf) {
+ if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) {
+ linphone_friend_save(lf, lf->lc);
+ count++;
+ }
+ linphone_friend_unref(lf);
+ }
+ vcards_iterator = bctbx_list_next(vcards_iterator);
+ }
+ bctbx_list_free(vcards);
+ linphone_core_store_friends_list_in_db(list->lc, list);
+ return count;
+
+}
+LinphoneStatus linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
+ bctbx_list_t *vcards = NULL;
if (!linphone_core_vcard_supported()) {
ms_error("vCard support wasn't enabled at compilation time");
@@ -1022,35 +1051,15 @@ LinphoneStatus linphone_friend_list_import_friends_from_vcard4_file(LinphoneFrie
}
vcards = linphone_vcard_context_get_vcard_list_from_file(list->lc->vcard_context, vcard_file);
- vcards_iterator = vcards;
if (!vcards) {
ms_error("Failed to parse the file %s", vcard_file);
return -1;
}
-
- while (vcards_iterator != NULL && bctbx_list_get_data(vcards_iterator) != NULL) {
- LinphoneVcard *vcard = (LinphoneVcard *)bctbx_list_get_data(vcards_iterator);
- LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
- if (lf) {
- if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) {
- linphone_friend_save(lf, lf->lc);
- count++;
- }
- linphone_friend_unref(lf);
- } else {
- linphone_vcard_unref(vcard);
- }
- vcards_iterator = bctbx_list_next(vcards_iterator);
- }
- bctbx_list_free(vcards);
- linphone_core_store_friends_list_in_db(list->lc, list);
- return count;
+ return linphone_friend_list_import_friends_from_vcard4(list,vcards);
}
LinphoneStatus linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *list, const char *vcard_buffer) {
bctbx_list_t *vcards = NULL;
- bctbx_list_t *vcards_iterator = NULL;
- int count = 0;
if (!linphone_core_vcard_supported()) {
ms_error("vCard support wasn't enabled at compilation time");
@@ -1062,29 +1071,12 @@ LinphoneStatus linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFr
}
vcards = linphone_vcard_context_get_vcard_list_from_buffer(list->lc->vcard_context, vcard_buffer);
- vcards_iterator = vcards;
if (!vcards) {
ms_error("Failed to parse the buffer");
return -1;
}
- while (vcards_iterator != NULL && bctbx_list_get_data(vcards_iterator) != NULL) {
- LinphoneVcard *vcard = (LinphoneVcard *)bctbx_list_get_data(vcards_iterator);
- LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
- if (lf) {
- if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) {
- count++;
- }
- linphone_friend_unref(lf);
- } else {
- linphone_vcard_unref(vcard);
- }
- vcards_iterator = bctbx_list_next(vcards_iterator);
- }
- bctbx_list_free(vcards);
- linphone_core_store_friends_list_in_db(list->lc, list);
- return count;
-}
+ return linphone_friend_list_import_friends_from_vcard4(list,vcards);}
void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
FILE *file = NULL;
diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c
index eeefc8577..fd3a4b5ab 100644
--- a/coreapi/linphonecall.c
+++ b/coreapi/linphonecall.c
@@ -41,6 +41,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mediastreamer2/mssndcard.h"
#include "mediastreamer2/msrtt4103.h"
+#include
+
static const char *EC_STATE_STORE = ".linphone.ecstate";
#define EC_STATE_MAX_LEN 1048576 // 1Mo
@@ -2152,6 +2154,10 @@ const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *cal
return call->dir==LinphoneCallIncoming ? call->log->from : call->log->to;
}
+const LinphoneAddress * linphone_call_get_to_address(const LinphoneCall *call){
+ return (const LinphoneAddress *)sal_op_get_to_address(call->op);
+}
+
char *linphone_call_get_remote_address_as_string(const LinphoneCall *call){
return linphone_address_as_string(linphone_call_get_remote_address(call));
}
@@ -2540,6 +2546,7 @@ static void setZrtpCryptoTypesParameters(MSZrtpParams *params, LinphoneCore *lc)
break;
case MS_AES_CM_256_SHA1_80:
ms_warning("Deprecated crypto suite MS_AES_CM_256_SHA1_80, use MS_AES_256_SHA1_80 instead");
+ BCTBX_NO_BREAK;
case MS_AES_256_SHA1_80:
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3;
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
@@ -3089,7 +3096,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m
*used_pt = payload_type_get_number(pt);
}
}
-
+
if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE){
ms_message("Payload type [%s/%i] has explicit bitrate [%i] kbit/s", pt->mime_type, pt->clock_rate, pt->normal_bitrate/1000);
pt->normal_bitrate=get_min_bandwidth(pt->normal_bitrate,bw*1000);
@@ -3797,6 +3804,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, LinphoneCallState nex
if (linphone_core_get_remote_ringback_tone(lc)){
call->playing_ringbacktone = TRUE;
}
+ BCTBX_NO_BREAK;
case LinphoneCallOutgoingEarlyMedia:
if (!call->params->real_early_media){
call->all_muted = TRUE;
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 395097823..4056c294b 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include
#include
#include
+#include
#include "mediastreamer2/dtmfgen.h"
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msequalizer.h"
@@ -400,6 +401,15 @@ void linphone_core_cbs_set_call_created(LinphoneCoreCbs *cbs, LinphoneCoreCbsCal
cbs->vtable->call_created = cb;
}
+LinphoneCoreCbsVersionUpdateCheckResultReceivedCb linphone_core_cbs_get_version_update_check_result_received(LinphoneCoreCbs *cbs) {
+ return cbs->vtable->version_update_check_result_received;
+}
+
+void linphone_core_cbs_set_version_update_check_result_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsVersionUpdateCheckResultReceivedCb cb) {
+ cbs->vtable->version_update_check_result_received = cb;
+}
+
+
typedef belle_sip_object_t_vptr_t LinphoneCore_vptr_t;
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCore);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneCore, belle_sip_object_t,
@@ -460,12 +470,16 @@ void linphone_core_set_log_level(OrtpLogLevel loglevel) {
case ORTP_TRACE:
case ORTP_DEBUG:
mask |= ORTP_DEBUG;
+ BCTBX_NO_BREAK;
case ORTP_MESSAGE:
mask |= ORTP_MESSAGE;
+ BCTBX_NO_BREAK;
case ORTP_WARNING:
mask |= ORTP_WARNING;
+ BCTBX_NO_BREAK;
case ORTP_ERROR:
mask |= ORTP_ERROR;
+ BCTBX_NO_BREAK;
case ORTP_FATAL:
mask |= ORTP_FATAL;
break;
@@ -2088,7 +2102,7 @@ static void linphone_core_internal_publish_state_changed(LinphoneCore *lc, Linph
const bctbx_list_t *item;
for (item = cfgs; item != NULL; item = bctbx_list_next(item)) {
LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)bctbx_list_get_data(item);
- if (cfg->long_term_event == lev) {
+ if (cfg->presence_publish_event == lev) {
linphone_proxy_config_notify_publish_state_changed(cfg, state);
break;
}
@@ -3441,9 +3455,8 @@ static void linphone_transfer_routes_to_op(bctbx_list_t *routes, SalOp *op){
bctbx_list_free(routes);
}
-void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact){
+void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact, LinphoneProxyConfig *proxy){
bctbx_list_t *routes=NULL;
- LinphoneProxyConfig *proxy=linphone_core_lookup_known_proxy(lc,dest);
const char *identity;
if (proxy){
identity=linphone_proxy_config_get_identity(proxy);
@@ -3473,6 +3486,9 @@ void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *d
}
sal_op_cnx_ip_to_0000_if_sendonly_enable(op,lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); /*also set in linphone_call_new_incoming*/
}
+void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact) {
+ linphone_configure_op_with_proxy(lc, op, dest, headers,with_contact,linphone_core_lookup_known_proxy(lc,dest));
+}
LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params){
const char *from=NULL;
@@ -3483,7 +3499,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
bool_t defer = FALSE;
LinphoneCallParams *cp;
- if (!(!linphone_call_params_audio_enabled(params) ||
+ if (!(!linphone_call_params_audio_enabled(params) ||
linphone_call_params_get_audio_direction(params) == LinphoneMediaDirectionInactive ||
linphone_call_params_get_local_conference_mode(params) == TRUE
)
@@ -3526,8 +3542,8 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
return NULL;
}
- /* this call becomes now the current one*/
- lc->current_call=call;
+ /* Unless this call is for a conference, it becomes now the current one*/
+ if (linphone_call_params_get_local_conference_mode(params) == FALSE) lc->current_call=call;
linphone_call_set_state (call,LinphoneCallOutgoingInit,"Starting outgoing call");
call->log->start_date_time=ms_time(NULL);
linphone_call_init_media_streams(call);
@@ -7238,3 +7254,143 @@ bool_t linphone_core_is_content_type_supported(const LinphoneCore *lc, const cha
void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type) {
sal_add_content_type_support(lc->sal, content_type);
}
+
+#ifdef ENABLE_UPDATE_CHECK
+static void update_check_process_terminated(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url) {
+ linphone_core_notify_version_update_check_result_received(lc, result, version, url);
+ if (lc->update_check_http_listener) {
+ belle_sip_object_unref(lc->update_check_http_listener);
+ lc->update_check_http_listener = NULL;
+ }
+ bctbx_free(lc->update_check_current_version);
+ lc->update_check_current_version = NULL;
+}
+
+typedef struct _parsed_version_st {
+ int major;
+ int minor;
+ int patch;
+} parsed_version_t;
+
+static int compare_parsed_versions(parsed_version_t current_version, parsed_version_t last_version) {
+ if (last_version.major > current_version.major) return 1;
+ if (last_version.minor > current_version.minor) return 1;
+ if (last_version.patch > current_version.patch) return 1;
+ return -1;
+}
+
+static void parse_version(const char *version, parsed_version_t *parsed_version) {
+ char *copy = bctbx_strdup(version);
+ char *ptr = copy;
+ char *next;
+ memset(parsed_version, 0, sizeof(parsed_version_t));
+ next = strchr(ptr, '.');
+ parsed_version->major = atoi(ptr);
+ ptr = next + 1;
+ next = strchr(ptr, '.');
+ parsed_version->minor = atoi(ptr);
+ if (next != NULL) {
+ ptr = next + 1;
+ parsed_version->patch = atoi(ptr);
+ }
+ bctbx_free(copy);
+}
+
+static bool_t update_is_available(const char *current_version, const char *last_version) {
+ parsed_version_t current_parsed_version;
+ parsed_version_t last_parsed_version;
+ parse_version(current_version, ¤t_parsed_version);
+ parse_version(last_version, &last_parsed_version);
+ return (compare_parsed_versions(current_parsed_version, last_parsed_version) > 0) ? TRUE : FALSE;
+}
+
+static void update_check_process_response_event(void *ctx, const belle_http_response_event_t *event) {
+ LinphoneCore *lc = (LinphoneCore *)ctx;
+
+ if (belle_http_response_get_status_code(event->response) == 200) {
+ belle_sip_message_t *message = BELLE_SIP_MESSAGE(event->response);
+ char *body = bctbx_strdup(belle_sip_message_get_body(message));
+ char *last_version = body;
+ char *url = strchr(body, '\t');
+ char *ptr;
+ if (url == NULL) {
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
+ bctbx_free(body);
+ return;
+ }
+ *url = '\0';
+ url++;
+ ptr = strrchr(url, '\r');
+ if (ptr != NULL) *ptr = '\0';
+ ptr = strrchr(url, '\n');
+ if (ptr != NULL) *ptr = '\0';
+ if (update_is_available(lc->update_check_current_version, last_version)) {
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckNewVersionAvailable, last_version, url);
+ } else {
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckUpToDate, NULL, NULL);
+ }
+ bctbx_free(body);
+ } else {
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
+ }
+}
+
+static void update_check_process_io_error(void *ctx, const belle_sip_io_error_event_t *event) {
+ LinphoneCore *lc = (LinphoneCore *)ctx;
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
+}
+
+static void update_check_process_timeout(void *ctx, const belle_sip_timeout_event_t *event) {
+ LinphoneCore *lc = (LinphoneCore *)ctx;
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
+}
+
+static void update_check_process_auth_requested(void *ctx, belle_sip_auth_event_t *event) {
+ LinphoneCore *lc = (LinphoneCore *)ctx;
+ update_check_process_terminated(lc, LinphoneVersionUpdateCheckError, NULL, NULL);
+}
+#endif /* ENABLE_UPDATE_CHECK */
+
+void linphone_core_check_for_update(LinphoneCore *lc, const char *current_version) {
+#ifdef ENABLE_UPDATE_CHECK
+ int err;
+ bool_t is_desktop = FALSE;
+ const char *platform = NULL;
+ const char *version_check_url_root = lp_config_get_string(lc->config, "misc", "version_check_url_root", NULL);
+
+ if (version_check_url_root != NULL) {
+ belle_http_request_listener_callbacks_t belle_request_listener = { 0 };
+ belle_http_request_t *request;
+ belle_generic_uri_t *uri;
+ char *version_check_url;
+ MSList *item;
+ MSList *platform_tags = ms_factory_get_platform_tags(linphone_core_get_ms_factory(lc));
+
+ for (item = platform_tags; item != NULL; item = ms_list_next(item)) {
+ const char *tag = (const char *)item->data;
+ if (strcmp(tag, "win32") == 0) platform = "windows";
+ else if (strcmp(tag, "apple") == 0) platform = "macosx";
+ else if (strcmp(tag, "linux") == 0) platform = "linux";
+ else if (strcmp(tag, "desktop") == 0) is_desktop = TRUE;
+ }
+ if ((is_desktop == FALSE) || (platform == NULL)) {
+ ms_warning("Update checking is not supported on this platform");
+ return;
+ }
+ version_check_url = bctbx_strdup_printf("%s/%s/RELEASE", version_check_url_root, platform);
+ uri = belle_generic_uri_parse(version_check_url);
+ ms_message("Checking for new version at: %s", version_check_url);
+ bctbx_free(version_check_url);
+
+ belle_request_listener.process_response = update_check_process_response_event;
+ belle_request_listener.process_auth_requested = update_check_process_auth_requested;
+ belle_request_listener.process_io_error = update_check_process_io_error;
+ belle_request_listener.process_timeout = update_check_process_timeout;
+
+ lc->update_check_current_version = bctbx_strdup(current_version);
+ lc->update_check_http_listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc);
+ request = belle_http_request_create("GET", uri, belle_sip_header_create("User-Agent", linphone_core_get_user_agent(lc)), NULL);
+ err = belle_http_provider_send_request(lc->http_provider, request, lc->update_check_http_listener);
+ }
+#endif
+}
diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc
index dda287d9a..e3efafde5 100644
--- a/coreapi/linphonecore_jni.cc
+++ b/coreapi/linphonecore_jni.cc
@@ -2872,6 +2872,10 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneProxyConfigImpl_getNatP
return (nat_policy != NULL) ? getNatPolicy(env, nat_policy) : NULL;
}
+extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setNatPolicy(JNIEnv* env,jobject thiz,jlong proxyCfg, jlong jnat_policy) {
+ linphone_proxy_config_set_nat_policy((LinphoneProxyConfig *)proxyCfg, (LinphoneNatPolicy *)jnat_policy);
+}
+
extern "C" jint Java_org_linphone_core_LinphoneProxyConfigImpl_setRoute(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jroute) {
if (jroute != NULL) {
const char* route = GetStringUTFChars(env, jroute);
@@ -5907,10 +5911,18 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setIncomingTimeout(JNIEn
linphone_core_set_inc_timeout((LinphoneCore *)lc, timeout);
}
+extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getIncomingTimeout(JNIEnv *env, jobject thiz, jlong lc) {
+ return linphone_core_get_inc_timeout((LinphoneCore *)lc);
+}
+
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setInCallTimeout(JNIEnv *env, jobject thiz, jlong lc, jint timeout) {
linphone_core_set_in_call_timeout((LinphoneCore *)lc, timeout);
}
+extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getInCallTimeout(JNIEnv *env, jobject thiz, jlong lc) {
+ return linphone_core_get_in_call_timeout((LinphoneCore *)lc);
+}
+
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getVersion(JNIEnv* env,jobject thiz,jlong ptr) {
jstring jvalue =env->NewStringUTF(linphone_core_get_version());
return jvalue;
diff --git a/coreapi/localplayer.c b/coreapi/localplayer.c
index ca433f1f1..88ecc06a8 100644
--- a/coreapi/localplayer.c
+++ b/coreapi/localplayer.c
@@ -36,7 +36,7 @@ LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, const char *
LinphonePlayer *obj = linphone_player_new();
MSSndCard *snd_card;
MSSndCardManager *snd_card_manager = ms_factory_get_snd_card_manager(lc->factory);
- if (sound_card_name == NULL) linphone_core_get_ringer_device(lc);
+ if (sound_card_name == NULL) sound_card_name = linphone_core_get_ringer_device(lc);
snd_card = ms_snd_card_manager_get_card(snd_card_manager, sound_card_name);
if (video_display_name == NULL) video_display_name = linphone_core_get_video_display_filter(lc);
obj->impl = ms_media_player_new(lc->factory, snd_card, video_display_name, window_id);
diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c
index 29b9a681c..07a46d347 100644
--- a/coreapi/lpconfig.c
+++ b/coreapi/lpconfig.c
@@ -481,8 +481,12 @@ LinphoneStatus linphone_config_read_file(LpConfig *lpconfig, const char *filenam
return -1;
}
-static char* _linphone_config_xml_convert(LpConfig *lpc, xml2lpc_context *context, int result) {
- char* error_msg = NULL;
+static const char *xml_to_lpc_failed = "xml to lpc failed";
+static const char *invalid_xml = "invalid xml";
+static const char *empty_xml = "empty provisioning file";
+
+static const char* _linphone_config_xml_convert(LpConfig *lpc, xml2lpc_context *context, int result) {
+ const char* error_msg = NULL;
if (result == 0) {
result = xml2lpc_convert(context, lpc);
if (result == 0) {
@@ -492,18 +496,18 @@ static char* _linphone_config_xml_convert(LpConfig *lpc, xml2lpc_context *contex
}
lp_config_sync(lpc);
} else {
- error_msg = "xml to lpc failed";
+ error_msg = xml_to_lpc_failed;
}
} else {
- error_msg = "invalid xml";
+ error_msg = invalid_xml;
}
return error_msg;
}
-char* linphone_config_load_from_xml_file(LinphoneConfig *lpc, const char *filename) {
+const char* linphone_config_load_from_xml_file(LinphoneConfig *lpc, const char *filename) {
xml2lpc_context *context = NULL;
char* path = lp_realpath(filename, NULL);
- char* error_msg = NULL;
+ const char* error_msg = NULL;
if (path) {
context = xml2lpc_context_new(NULL, NULL);
@@ -526,22 +530,24 @@ static void xml2lpc_callback(void *ctx, xml2lpc_log_level level, const char *fmt
bctbx_logv(BCTBX_LOG_DOMAIN, bctbx_level,fmt,list);
}
-char* _linphone_config_load_from_xml_string(LpConfig *lpc, const char *buffer) {
+const char* _linphone_config_load_from_xml_string(LpConfig *lpc, const char *buffer) {
xml2lpc_context *context = NULL;
- char* error_msg = NULL;
+ const char* error_msg = NULL;
if (buffer != NULL) {
context = xml2lpc_context_new(xml2lpc_callback, NULL);
error_msg = _linphone_config_xml_convert(lpc, context, xml2lpc_set_xml_string(context, buffer));
+ }else{
+ error_msg = empty_xml;
}
if (context) xml2lpc_context_destroy(context);
return error_msg;
}
+
LinphoneStatus linphone_config_load_from_xml_string(LpConfig *lpc, const char *buffer) {
- char *status;
+ const char *status;
if ((status =_linphone_config_load_from_xml_string(lpc,buffer))) {
ms_error("%s",status);
- //ms_free(status)
return -1;
} else
return 0;
diff --git a/coreapi/presence.c b/coreapi/presence.c
index 12fb8f834..30d986c2f 100644
--- a/coreapi/presence.c
+++ b/coreapi/presence.c
@@ -1229,6 +1229,7 @@ static int process_pidf_xml_presence_service_notes(xmlparsing_context_t *xml_ctx
static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, LinphonePresenceModel *model) {
char xpath_str[MAX_XPATH_LENGTH];
xmlXPathObjectPtr service_object;
+ xmlXPathObjectPtr pidfonline_object;
LinphonePresenceService *service;
const char *basic_status_str;
const char *service_id_str;
@@ -1256,7 +1257,9 @@ static int process_pidf_xml_presence_services(xmlparsing_context_t *xml_ctx, Lin
}
snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/pidf:status/pidfonline:online", service_prefix, i);
- if (linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str) != NULL) {
+ if ((pidfonline_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, xpath_str)) != NULL
+ && pidfonline_object->nodesetval
+ && pidfonline_object->nodesetval->nodeNr >0) {
model->is_online = TRUE;
}
diff --git a/coreapi/private.h b/coreapi/private.h
index 1bd94ac8e..1825583cc 100644
--- a/coreapi/private.h
+++ b/coreapi/private.h
@@ -454,7 +454,7 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc);
void _linphone_proxy_config_release(LinphoneProxyConfig *cfg);
void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj);
void linphone_proxy_config_notify_publish_state_changed(LinphoneProxyConfig *cfg, LinphonePublishState state);
-
+LinphoneEvent *linphone_proxy_config_create_publish(LinphoneProxyConfig *cfg, const char *event, int expires);
/*
* returns service route as defined in as defined by rfc3608, might be a list instead of just one.
* Can be NULL
@@ -468,10 +468,10 @@ void _linphone_friend_list_release(LinphoneFriendList *list);
/*get rls either from list or core if any*/
const LinphoneAddress * _linphone_friend_list_get_rls_address(const LinphoneFriendList *list);
-void linphone_friend_invalidate_subscription(LinphoneFriend *lf);
+LINPHONE_PUBLIC void linphone_friend_invalidate_subscription(LinphoneFriend *lf);
void linphone_friend_close_subscriptions(LinphoneFriend *lf);
void _linphone_friend_release(LinphoneFriend *lf);
-void linphone_friend_update_subscribes(LinphoneFriend *fr, bool_t only_when_registered);
+LINPHONE_PUBLIC void linphone_friend_update_subscribes(LinphoneFriend *fr, bool_t only_when_registered);
void linphone_friend_notify(LinphoneFriend *lf, LinphonePresenceModel *presence);
void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc);
void linphone_friend_add_incoming_subscription(LinphoneFriend *lf, SalOp *op);
@@ -702,7 +702,7 @@ struct _LinphoneProxyConfig
bool_t unused[3];
/*---*/
LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/
- LinphoneEvent *long_term_event;
+ LinphoneEvent *presence_publish_event;
unsigned long long previous_publish_config_hash[2];
char *refkey;
@@ -1110,6 +1110,10 @@ struct _LinphoneCore
belle_http_provider_t *http_provider;
belle_tls_crypto_config_t *http_crypto_config;
belle_http_request_listener_t *provisioning_http_listener;
+#ifdef ENABLE_UPDATE_CHECK
+ belle_http_request_listener_t *update_check_http_listener;
+ char *update_check_current_version;
+#endif
MSList *tones;
LinphoneReason chat_deny_code;
char *file_transfer_server;
@@ -1266,7 +1270,7 @@ void call_logs_write_to_config_file(LinphoneCore *lc);
void linphone_core_call_log_storage_init(LinphoneCore *lc);
void linphone_core_call_log_storage_close(LinphoneCore *lc);
void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log);
-const MSList *linphone_core_get_call_history(LinphoneCore *lc);
+LINPHONE_PUBLIC const MSList *linphone_core_get_call_history(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_delete_call_history(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_delete_call_log(LinphoneCore *lc, LinphoneCallLog *log);
LINPHONE_PUBLIC int linphone_core_get_call_history_size(LinphoneCore *lc);
@@ -1293,6 +1297,7 @@ void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID id);
bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc);
const char *linphone_core_create_uuid(LinphoneCore *lc);
void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact);
+void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact, LinphoneProxyConfig *proxy);
void linphone_call_create_op(LinphoneCall *call);
int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer);
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, SalBodyHandler *body);
@@ -1921,6 +1926,7 @@ void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore
void linphone_core_notify_friend_list_created(LinphoneCore *lc, LinphoneFriendList *list);
void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendList *list);
void linphone_core_notify_call_created(LinphoneCore *lc, LinphoneCall *call);
+void linphone_core_notify_version_update_check_result_received(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url);
void set_mic_gain_db(AudioStream *st, float gain);
void set_playback_gain_db(AudioStream *st, float gain);
@@ -2029,10 +2035,10 @@ LinphoneVideoDefinition * linphone_video_definition_new(unsigned int width, unsi
LinphoneVideoDefinition * linphone_factory_find_supported_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height);
LinphoneVideoDefinition * linphone_factory_find_supported_video_definition_by_name(const LinphoneFactory *factory, const char *name);
-char* _linphone_config_load_from_xml_string(LpConfig *lpc, const char *buffer);
+const char* _linphone_config_load_from_xml_string(LpConfig *lpc, const char *buffer);
LinphoneNatPolicy * linphone_config_create_nat_policy_from_section(const LinphoneConfig *config, const char* section);
-
-
+
+
#ifdef __cplusplus
}
#endif
diff --git a/coreapi/proxy.c b/coreapi/proxy.c
index f6300e0ef..463be992d 100644
--- a/coreapi/proxy.c
+++ b/coreapi/proxy.c
@@ -127,6 +127,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
cfg->avpf_mode = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf", LinphoneAVPFDefault) : LinphoneAVPFDefault;
cfg->avpf_rr_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf_rr_interval", 5) : 5;
cfg->publish_expires= lc ? lp_config_get_default_int(lc->config, "proxy", "publish_expires", -1) : -1;
+ cfg->publish = lc ? lp_config_get_default_int(lc->config, "proxy", "publish", FALSE) : FALSE;
cfg->refkey = refkey ? ms_strdup(refkey) : NULL;
if (nat_policy_ref) {
LinphoneNatPolicy *policy = linphone_config_create_nat_policy_from_section(lc->config,nat_policy_ref);
@@ -209,10 +210,10 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *cfg){
sal_op_release(cfg->op);
cfg->op=NULL;
}
- if (cfg->long_term_event){
- linphone_event_terminate(cfg->long_term_event);
- linphone_event_unref(cfg->long_term_event);
- cfg->long_term_event=NULL;
+ if (cfg->presence_publish_event){
+ linphone_event_terminate(cfg->presence_publish_event);
+ linphone_event_unref(cfg->presence_publish_event);
+ cfg->presence_publish_event=NULL;
}
}
@@ -391,8 +392,8 @@ void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){
linphone_proxy_config_store_server_config(cfg);
linphone_proxy_config_compute_publish_params_hash(cfg);
- if (cfg->publish && cfg->long_term_event){
- linphone_event_pause_publish(cfg->long_term_event);
+ if (cfg->publish && cfg->presence_publish_event){
+ linphone_event_pause_publish(cfg->presence_publish_event);
}
/*Don't stop refresher*/
}
@@ -415,11 +416,11 @@ void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig * cfg){
cfg->pending_contact=contact_addr;
}
- if (cfg->long_term_event){ /*might probably do better*/
- linphone_event_terminate(cfg->long_term_event);
- if (cfg->long_term_event) {
- linphone_event_unref(cfg->long_term_event); /*probably useless as cfg->long_term_event is already unref in linphone_proxy_config_notify_publish_state_changed. To be check with Ghislain*/
- cfg->long_term_event=NULL;
+ if (cfg->presence_publish_event){ /*might probably do better*/
+ linphone_event_terminate(cfg->presence_publish_event);
+ if (cfg->presence_publish_event) {
+ linphone_event_unref(cfg->presence_publish_event); /*probably useless as cfg->long_term_event is already unref in linphone_proxy_config_notify_publish_state_changed. To be check with Ghislain*/
+ cfg->presence_publish_event=NULL;
}
}
@@ -800,7 +801,7 @@ LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg)
sal_op_unref(cfg->op); /*but we keep refresher to handle authentication if needed*/
cfg->op=NULL;
}
- if (cfg->long_term_event) {
+ if (cfg->presence_publish_event) {
if (res == LinphoneProxyConfigAddressDifferent) {
_linphone_proxy_config_unpublish(cfg);
}
@@ -817,16 +818,16 @@ LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg)
if (linphone_proxy_config_compute_publish_params_hash(cfg)) {
ms_message("Publish params have changed on proxy config [%p]",cfg);
- if (cfg->long_term_event) {
+ if (cfg->presence_publish_event) {
if (cfg->publish) {
- const char * sip_etag = linphone_event_get_custom_header(cfg->long_term_event, "SIP-ETag");
+ const char * sip_etag = linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag");
if (sip_etag) {
if (cfg->sip_etag) ms_free(cfg->sip_etag);
cfg->sip_etag = ms_strdup(sip_etag);
}
}
/*publish is terminated*/
- linphone_event_terminate(cfg->long_term_event);
+ linphone_event_terminate(cfg->presence_publish_event);
}
if (cfg->publish) cfg->send_publish=TRUE;
} else {
@@ -855,14 +856,13 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
if (proxy->state==LinphoneRegistrationOk || proxy->state==LinphoneRegistrationCleared){
LinphoneContent *content;
char *presence_body;
- if (proxy->long_term_event==NULL){
- proxy->long_term_event = linphone_core_create_publish(proxy->lc
- , linphone_proxy_config_get_identity_address(proxy)
+ if (proxy->presence_publish_event==NULL){
+ proxy->presence_publish_event = linphone_proxy_config_create_publish(proxy
, "presence"
, linphone_proxy_config_get_publish_expires(proxy));
- linphone_event_ref(proxy->long_term_event);
+ linphone_event_ref(proxy->presence_publish_event);
}
- proxy->long_term_event->internal = TRUE;
+ proxy->presence_publish_event->internal = TRUE;
if (linphone_presence_model_get_presentity(presence) == NULL) {
ms_message("No presentity set for model [%p], using identity from proxy config [%p]", presence, proxy);
@@ -879,11 +879,11 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
linphone_content_set_type(content, "application");
linphone_content_set_subtype(content,"pidf+xml");
if (proxy->sip_etag) {
- linphone_event_add_custom_header(proxy->long_term_event, "SIP-If-Match", proxy->sip_etag);
+ linphone_event_add_custom_header(proxy->presence_publish_event, "SIP-If-Match", proxy->sip_etag);
ms_free(proxy->sip_etag);
proxy->sip_etag=NULL;
}
- err = linphone_event_send_publish(proxy->long_term_event, content);
+ err = linphone_event_send_publish(proxy->presence_publish_event, content);
linphone_content_unref(content);
ms_free(presence_body);
}else proxy->send_publish=TRUE; /*otherwise do not send publish if registration is in progress, this will be done later*/
@@ -891,10 +891,10 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
}
void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj) {
- if (obj->long_term_event
- && (linphone_event_get_publish_state(obj->long_term_event) == LinphonePublishOk ||
- (linphone_event_get_publish_state(obj->long_term_event) == LinphonePublishProgress && obj->publish_expires != 0))) {
- linphone_event_unpublish(obj->long_term_event);
+ if (obj->presence_publish_event
+ && (linphone_event_get_publish_state(obj->presence_publish_event) == LinphonePublishOk ||
+ (linphone_event_get_publish_state(obj->presence_publish_event) == LinphonePublishProgress && obj->publish_expires != 0))) {
+ linphone_event_unpublish(obj->presence_publish_event);
}
if (obj->sip_etag) {
ms_free(obj->sip_etag);
@@ -1464,8 +1464,8 @@ void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatP
}
void linphone_proxy_config_notify_publish_state_changed(LinphoneProxyConfig *cfg, LinphonePublishState state) {
- if ((cfg->long_term_event != NULL) && ((state == LinphonePublishCleared) || (state == LinphonePublishError))) {
- linphone_event_unref(cfg->long_term_event);
- cfg->long_term_event = NULL;
+ if ((cfg->presence_publish_event != NULL) && ((state == LinphonePublishCleared) || (state == LinphonePublishError))) {
+ linphone_event_unref(cfg->presence_publish_event);
+ cfg->presence_publish_event = NULL;
}
}
diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c
index 44b8dd43d..cc036e6f4 100644
--- a/coreapi/remote_provisioning.c
+++ b/coreapi/remote_provisioning.c
@@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml) {
- char* error_msg = _linphone_config_load_from_xml_string(linphone_core_get_config(lc), xml);
+ const char* error_msg = _linphone_config_load_from_xml_string(linphone_core_get_config(lc), xml);
linphone_configuring_terminated(lc
,error_msg ? LinphoneConfiguringFailed : LinphoneConfiguringSuccessful
diff --git a/coreapi/upnp.c b/coreapi/upnp.c
index c1681918a..642eb24bc 100644
--- a/coreapi/upnp.c
+++ b/coreapi/upnp.c
@@ -749,8 +749,8 @@ int linphone_call_update_upnp(LinphoneCall *call) {
}
void linphone_call_update_upnp_state_in_call_stats(LinphoneCall *call) {
- call->stats[LINPHONE_CALL_STATS_AUDIO].upnp_state = call->upnp_session->audio->state;
- call->stats[LINPHONE_CALL_STATS_VIDEO].upnp_state = call->upnp_session->video->state;
+ call->audio_stats->upnp_state = call->upnp_session->audio->state;
+ call->video_stats->upnp_state = call->upnp_session->video->state;
}
void linphone_upnp_update_stream_state(UpnpStream *stream) {
@@ -1274,8 +1274,8 @@ void linphone_upnp_session_destroy(UpnpSession *session) {
}
}
- session->call->stats[LINPHONE_CALL_STATS_AUDIO].upnp_state = LinphoneUpnpStateKo;
- session->call->stats[LINPHONE_CALL_STATS_VIDEO].upnp_state = LinphoneUpnpStateKo;
+ session->call->audio_stats->upnp_state = LinphoneUpnpStateKo;
+ session->call->video_stats->upnp_state = LinphoneUpnpStateKo;
linphone_upnp_stream_destroy(session->audio);
linphone_upnp_stream_destroy(session->video);
diff --git a/coreapi/vtables.c b/coreapi/vtables.c
index d48342b36..ca9960ef9 100644
--- a/coreapi/vtables.c
+++ b/coreapi/vtables.c
@@ -316,6 +316,11 @@ void linphone_core_notify_call_created(LinphoneCore *lc, LinphoneCall *call) {
cleanup_dead_vtable_refs(lc);
}
+void linphone_core_notify_version_update_check_result_received(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url) {
+ NOTIFY_IF_EXIST(version_update_check_result_received, lc, result, version, url);
+ cleanup_dead_vtable_refs(lc);
+}
+
static VTableReference * v_table_reference_new(LinphoneCoreCbs *cbs, bool_t internal){
VTableReference *ref=ms_new0(VTableReference,1);
ref->valid=TRUE;
diff --git a/gtk/main.c b/gtk/main.c
index 85ec6d36d..579fc8296 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "linphone/lpconfig.h"
#include "liblinphone_gitversion.h"
#include
+#include
#include
#include
@@ -303,7 +304,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
if (chat_messages_db_file) linphone_core_set_chat_database_path(the_core,chat_messages_db_file);
if (call_logs_db_file) linphone_core_set_call_logs_database_path(the_core, call_logs_db_file);
if (friends_db_file) linphone_core_set_friends_database_path(the_core, friends_db_file);
-
+
// Disable the generic OpenGL displaying filter
msfactory = linphone_core_get_ms_factory(the_core);
ogl_filter_desc = ms_factory_lookup_filter_by_id(msfactory, MS_OGL_ID);
@@ -1417,6 +1418,7 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
case LinphoneCallPausing:
linphone_gtk_enable_hold_button(call,TRUE,FALSE);
linphone_gtk_call_update_tab_header(call,FALSE);
+ BCTBX_NO_BREAK;
case LinphoneCallPausedByRemote:
linphone_gtk_in_call_view_set_paused(call);
linphone_gtk_call_update_tab_header(call,TRUE);
diff --git a/include/linphone/address.h b/include/linphone/address.h
index f7eef3f5c..f92ff36f3 100644
--- a/include/linphone/address.h
+++ b/include/linphone/address.h
@@ -201,6 +201,12 @@ LINPHONE_PUBLIC const char *linphone_address_get_password(const LinphoneAddress
**/
LINPHONE_PUBLIC void linphone_address_set_header(LinphoneAddress *addr, const char *header_name, const char *header_value);
+/**
+ * Get the header encoded in the address.
+ * @param addr the address
+**/
+LINPHONE_PUBLIC const char * linphone_address_get_header(const LinphoneAddress *addr, const char *name);
+
LINPHONE_PUBLIC bool_t linphone_address_has_param(const LinphoneAddress *addr, const char *name);
LINPHONE_PUBLIC const char * linphone_address_get_param(const LinphoneAddress *addr, const char *name);
diff --git a/include/linphone/call.h b/include/linphone/call.h
index 7ef92c41a..c7749e536 100644
--- a/include/linphone/call.h
+++ b/include/linphone/call.h
@@ -91,6 +91,11 @@ LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
**/
LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call);
+/**
+ * Returns the to address with its headers associated to this call
+**/
+LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_to_address(const LinphoneCall * call);
+
/**
* Returns the remote address associated to this call as a string.
* The result string must be freed by user using ms_free().
@@ -221,6 +226,11 @@ LINPHONE_PUBLIC const char *linphone_call_get_remote_user_agent(LinphoneCall *ca
**/
LINPHONE_PUBLIC const char *linphone_call_get_remote_contact(LinphoneCall *call);
+/**
+ * Returns the ZRTP authentication token to verify.
+ * @param call the LinphoneCall
+ * @return the authentication token to verify.
+**/
LINPHONE_PUBLIC const char * linphone_call_get_authentication_token(LinphoneCall *call);
/**
diff --git a/include/linphone/callbacks.h b/include/linphone/callbacks.h
index b9dd4b7a1..067d6ca11 100644
--- a/include/linphone/callbacks.h
+++ b/include/linphone/callbacks.h
@@ -486,6 +486,14 @@ typedef void (*LinphoneCoreCbsFriendListRemovedCb) (LinphoneCore *lc, LinphoneFr
*/
typedef LinphoneCoreCbsFriendListRemovedCb LinphoneCoreFriendListRemovedCb;
+/**
+ * Callback prototype for reporting the result of a version update check.
+ * @param[in] lc LinphoneCore object
+ * @param[in] result The result of the version update check
+ * @param[in] url The url where to download the new version if the result is LinphoneVersionUpdateCheckNewVersionAvailable
+ */
+typedef void (*LinphoneCoreCbsVersionUpdateCheckResultReceivedCb) (LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url);
+
/**
* @}
**/
diff --git a/include/linphone/core.h b/include/linphone/core.h
index 434993a1d..463f95f78 100644
--- a/include/linphone/core.h
+++ b/include/linphone/core.h
@@ -113,6 +113,13 @@ LINPHONE_PUBLIC LinphonePlayer *linphone_core_create_local_player(LinphoneCore *
**/
LINPHONE_PUBLIC LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore*lc);
+/**
+ * Checks if a new version of the application is available.
+ * @param lc LinphoneCore object
+ * @param current_version The current version of the application
+ */
+LINPHONE_PUBLIC void linphone_core_check_for_update(LinphoneCore *lc, const char *current_version);
+
/**
* @}
*/
@@ -208,6 +215,7 @@ typedef struct _LinphoneCoreVTable{
LinphoneCoreFriendListCreatedCb friend_list_created;
LinphoneCoreFriendListRemovedCb friend_list_removed;
LinphoneCoreCbsCallCreatedCb call_created;
+ LinphoneCoreCbsVersionUpdateCheckResultReceivedCb version_update_check_result_received;
void *user_data; /**
#ifdef _WIN32
#define unlink _unlink
@@ -396,8 +397,8 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr
wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_callee.number_of_LinphoneCallEncryptedOn+1);
/* when caller is encryptionNone but callee is ZRTP, we expect ZRTP to take place */
- if ((linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionNone)
- && (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
+ if ((linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionNone)
+ && (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
&& linphone_core_media_encryption_supported(caller_mgr->lc, LinphoneMediaEncryptionZRTP)) {
const LinphoneCallParams* call_param = linphone_call_get_current_params(callee_call);
BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param), LinphoneMediaEncryptionZRTP, int, "%d");
@@ -1002,56 +1003,202 @@ static void simple_call_compatibility_mode(void) {
static void terminate_call_with_error(void) {
LinphoneCall* call_callee ;
LinphoneErrorInfo *ei ;
- const LinphoneErrorInfo *rei ;
+ const LinphoneErrorInfo *rei = NULL;
LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
-
- LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity);
+ LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity);
linphone_call_ref(out_call);
ei = linphone_error_info_new();
- linphone_error_info_set(ei, NULL, LinphoneReasonNone, 200, "Call completed elsewhere", NULL);
+ linphone_error_info_set(ei, NULL, LinphoneReasonNone, 200, "Call refused for security reason", NULL);
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1));
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, 1));
-
+
call_callee = linphone_core_get_current_call(callee_mgr->lc);
+ linphone_call_ref(call_callee);
BC_ASSERT_PTR_NOT_NULL(call_callee);
-
+
BC_ASSERT_EQUAL( linphone_core_accept_call(callee_mgr->lc,call_callee), 0 , int, "%d");
BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,1));
-
-
BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
-
+ BC_ASSERT_PTR_NOT_NULL(ei);
+ if (ei){
+ BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),200, int, "%d");
+ BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(ei), "Call refused for security reason");
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(ei), "SIP");
+ }
+ linphone_call_terminate_with_error_info(out_call,ei);
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEnd,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1));
- rei = ei;
-
- linphone_call_terminate_with_error_info(out_call,rei);
- BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1));
+ rei = linphone_call_get_error_info(call_callee);
+ BC_ASSERT_PTR_NOT_NULL(rei);
+ if (rei){
+ BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(rei),200, int, "%d");
+ BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(rei));
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rei), "Call refused for security reason");
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(ei), "SIP");
+ }
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1));
+
+ linphone_error_info_unref(ei);
+ linphone_call_unref(out_call);
+ linphone_call_unref(call_callee);
+ linphone_core_manager_destroy(callee_mgr);
+ linphone_core_manager_destroy(caller_mgr);
+}
+
+static void cancel_call_with_error(void) {
+ LinphoneCall* call_callee ;
+ LinphoneErrorInfo *ei ;
+ const LinphoneErrorInfo *rei = NULL;
+ LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+
+ LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity);
+
+ linphone_call_ref(out_call);
+ ei = linphone_error_info_new();
+ linphone_error_info_set(ei, NULL, LinphoneReasonNone, 600, "Call has been cancelled", NULL);
+
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, 1));
+
+ call_callee = linphone_core_get_current_call(callee_mgr->lc);
+ linphone_call_ref(call_callee);
+
+ BC_ASSERT_PTR_NOT_NULL(call_callee);
+ BC_ASSERT_PTR_NOT_NULL(ei);
+ if (ei){
+ BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),600, int, "%d");
+ BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(ei), "Call has been cancelled");
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(ei), "SIP");
+ }
+ linphone_call_terminate_with_error_info(out_call,ei);
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEnd,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1));
+
+ rei = linphone_call_get_error_info(call_callee);
+ BC_ASSERT_PTR_NOT_NULL(rei);
+ if (rei){
+ BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(rei),600, int, "%d");
+ BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(rei));
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rei), "Call has been cancelled");
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rei), "SIP");
+ }
+
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1));
+
+ linphone_error_info_unref(ei);
+ linphone_call_unref(out_call);
+ linphone_call_unref(call_callee);
+ linphone_core_manager_destroy(callee_mgr);
+ linphone_core_manager_destroy(caller_mgr);
+}
+
+static void cancel_other_device_after_accept(void) {
+ LinphoneCall* call_callee;
+ LinphoneCall* call_callee_2;
+ const LinphoneErrorInfo *rei = NULL;
+ LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager *callee_mgr_2 = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+
+ LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity);
+ linphone_call_ref(out_call);
+
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, 1));
+ call_callee = linphone_core_get_current_call(callee_mgr->lc);
+ linphone_call_ref(call_callee);
+ BC_ASSERT_PTR_NOT_NULL(call_callee);
+
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr_2->lc, &callee_mgr_2->stat.number_of_LinphoneCallIncomingReceived, 1));
+ call_callee_2 = linphone_core_get_current_call(callee_mgr_2->lc);
+ linphone_call_ref(call_callee_2);
+ BC_ASSERT_PTR_NOT_NULL(call_callee_2);
+
+ BC_ASSERT_EQUAL( linphone_call_accept(call_callee), 0 , int, "%d");
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr_2->lc,&callee_mgr_2->stat.number_of_LinphoneCallEnd,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr_2->lc,&callee_mgr_2->stat.number_of_LinphoneCallReleased,1));
+
+ rei = linphone_call_get_error_info(call_callee_2);
BC_ASSERT_PTR_NOT_NULL(rei);
if (rei){
BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(rei),200, int, "%d");
BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(rei));
BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rei), "Call completed elsewhere");
- BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(ei), "SIP");
-
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rei), "SIP");
}
-
- BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallEnd,1, int, "%d");
+ linphone_call_terminate(out_call);
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1));
BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1));
-
- linphone_error_info_unref(ei);
+
linphone_call_unref(out_call);
+ linphone_call_unref(call_callee);
+ linphone_call_unref(call_callee_2);
linphone_core_manager_destroy(callee_mgr);
+ linphone_core_manager_destroy(callee_mgr_2);
linphone_core_manager_destroy(caller_mgr);
}
+static void cancel_other_device_after_decline(void) {
+ LinphoneCall* call_callee;
+ LinphoneCall* call_callee_2;
+ const LinphoneErrorInfo *rei = NULL;
+ LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager *callee_mgr_2 = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+
+ LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity);
+ linphone_call_ref(out_call);
+
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, 1));
+ call_callee = linphone_core_get_current_call(callee_mgr->lc);
+ linphone_call_ref(call_callee);
+ BC_ASSERT_PTR_NOT_NULL(call_callee);
+
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr_2->lc, &callee_mgr_2->stat.number_of_LinphoneCallIncomingReceived, 1));
+ call_callee_2 = linphone_core_get_current_call(callee_mgr_2->lc);
+ linphone_call_ref(call_callee_2);
+ BC_ASSERT_PTR_NOT_NULL(call_callee_2);
+
+ BC_ASSERT_EQUAL(linphone_call_decline(call_callee, LinphoneReasonDeclined), 0 , int, "%d");
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallReleased, 1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr_2->lc,&callee_mgr_2->stat.number_of_LinphoneCallEnd,1));
+ BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr_2->lc,&callee_mgr_2->stat.number_of_LinphoneCallReleased,1));
+
+ rei = linphone_call_get_error_info(call_callee_2);
+ BC_ASSERT_PTR_NOT_NULL(rei);
+ if (rei){
+ BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(rei),600, int, "%d");
+ BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(rei));
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rei), "Busy Everywhere");
+ BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rei), "SIP");
+ }
+
+ linphone_call_unref(out_call);
+ linphone_call_unref(call_callee);
+ linphone_call_unref(call_callee_2);
+ linphone_core_manager_destroy(callee_mgr);
+ linphone_core_manager_destroy(callee_mgr_2);
+ linphone_core_manager_destroy(caller_mgr);
+}
static void cancelled_call(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
@@ -1154,8 +1301,14 @@ static void early_cancelled_call(void) {
static void cancelled_ringing_call(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
-
- LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity);
+ const bctbx_list_t * call_history;
+ LinphoneCall* out_call;
+
+ char * db_path= bctbx_strdup_printf("%s,%s",bc_tester_get_writable_dir_prefix(),"tmp_call_log.db");
+ linphone_core_set_call_logs_database_path(marie->lc,db_path);
+
+
+ out_call = linphone_core_invite_address(pauline->lc,marie->identity);
linphone_call_ref(out_call);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallIncomingReceived,1));
@@ -1164,10 +1317,18 @@ static void cancelled_ringing_call(void) {
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallReleased,1));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallEnd,1, int, "%d");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallEnd,1, int, "%d");
-
+
+ call_history = linphone_core_get_call_history(marie->lc);
+ BC_ASSERT_PTR_NOT_NULL(call_history);
+ BC_ASSERT_EQUAL(bctbx_list_size(call_history),1, int,"%i");
+ BC_ASSERT_EQUAL(linphone_call_log_get_status((LinphoneCallLog*)bctbx_list_get_data(call_history)), LinphoneCallMissed, LinphoneCallStatus, "%i");
+
linphone_call_unref(out_call);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
+ unlink(db_path);
+ bctbx_free(db_path);
+
}
static void early_declined_call(void) {
@@ -1213,24 +1374,24 @@ static void call_busy_when_calling_self(void) {
static void call_declined_with_error(void) {
LinphoneCoreManager* callee_mgr = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
-
+
LinphoneCall* in_call = NULL;
LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity);
LinphoneFactory* factory = linphone_factory_get();
const LinphoneErrorInfo* rcvd_ei;
const LinphoneErrorInfo* sub_rcvd_ei;
-
+
LinphoneErrorInfo *ei = linphone_factory_create_error_info(factory);
LinphoneErrorInfo *reason_ei = linphone_factory_create_error_info(factory);
-
+
linphone_error_info_set(ei, "SIP", LinphoneReasonUnknown, 603, "Decline", NULL); //ordre des arguments à vérifier
linphone_error_info_set(reason_ei, "hardware", LinphoneReasonUnknown, 66, "J'ai plus de batterie", NULL);
linphone_error_info_set_sub_error_info(ei, reason_ei);
-
+
BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived,1));
BC_ASSERT_PTR_NOT_NULL(in_call=linphone_core_get_current_call(callee_mgr->lc));
-
+
linphone_call_ref(out_call);
BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived,1));
BC_ASSERT_PTR_NOT_NULL(in_call=linphone_core_get_current_call(callee_mgr->lc));
@@ -1243,7 +1404,7 @@ static void call_declined_with_error(void) {
rcvd_ei = linphone_call_get_error_info(out_call);
sub_rcvd_ei = linphone_error_info_get_sub_error_info(rcvd_ei);
-
+
BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rcvd_ei), "Decline");
BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rcvd_ei), "SIP");
BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(sub_rcvd_ei), "J'ai plus de batterie");
@@ -1253,8 +1414,8 @@ static void call_declined_with_error(void) {
BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(in_call)),LinphoneCallDeclined, int, "%d");
BC_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonDeclined, int, "%d");
BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(out_call)),LinphoneCallDeclined, int, "%d");
-
-
+
+
BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1));
BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1));
linphone_call_unref(in_call);
@@ -1346,7 +1507,7 @@ int check_nb_media_starts(LinphoneCoreManager *caller, LinphoneCoreManager *call
BC_ASSERT_PTR_NOT_NULL(c1);
BC_ASSERT_PTR_NOT_NULL(c2);
if (!c1 || !c2) return FALSE;
-
+
if (c1) {
c1_ret = c1->nb_media_starts == caller_nb_media_starts;
BC_ASSERT_EQUAL(c1->nb_media_starts, caller_nb_media_starts, unsigned int, "%u");
@@ -1477,7 +1638,7 @@ static void ice_added_by_reinvite(void){
lp_config_set_int(linphone_core_get_config(marie->lc), "net", "allow_late_ice", 1);
lp_config_set_int(linphone_core_get_config(pauline->lc), "net", "allow_late_ice", 1);
-
+
BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
if (!call_ok) goto end;
liblinphone_tester_check_rtcp(marie,pauline);
@@ -1539,7 +1700,7 @@ static void call_with_custom_headers(void) {
linphone_call_params_add_custom_header(params,"Working","yes");
if (!BC_ASSERT_TRUE(call_with_caller_params(pauline,marie,params))) goto end;
-
+
call_marie=linphone_core_get_current_call(marie->lc);
call_pauline=linphone_core_get_current_call(pauline->lc);
@@ -1576,7 +1737,7 @@ static void call_with_custom_headers(void) {
ms_free(marie_remote_contact_header);
end_call(pauline, marie);
-
+
end:
linphone_call_params_unref(params);
linphone_core_manager_destroy(marie);
@@ -1657,7 +1818,7 @@ static void call_with_custom_sdp_attributes(void) {
static void call_with_custom_header_or_sdp_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) {
-
+
const char *value;
if (cstate == LinphoneCallOutgoingInit){
@@ -1698,7 +1859,7 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
LinphoneCallParams *caller_params; // *callee_params ;
LinphoneCoreVTable *vtable;
-
+
LinphoneCallTestParams caller_test_params = {0};
LinphoneCallTestParams callee_test_params = {0};
@@ -1706,7 +1867,7 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
stats initial_callee=callee_mgr->stat;
bool_t result=FALSE;
bool_t did_receive_call;
-
+
//Create caller params with custom header and custom SDP
caller_params = linphone_core_create_call_params(caller_mgr->lc, NULL);
linphone_call_params_add_custom_header(caller_params, "weather", "thunderstorm");
@@ -1714,24 +1875,24 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
caller_test_params.base = (LinphoneCallParams*)caller_params;
callee_test_params.base = NULL;
-
+
/* TODO: This should be handled correctly inside the liblinphone library but meanwhile handle this here. */
linphone_core_manager_wait_for_stun_resolution(caller_mgr);
linphone_core_manager_wait_for_stun_resolution(callee_mgr);
-
+
setup_sdp_handling(&caller_test_params, caller_mgr);
setup_sdp_handling(&callee_test_params, callee_mgr);
-
+
// Assign dedicated callback to vtable for caller and callee
vtable = linphone_core_v_table_new();
vtable->call_state_changed = call_with_custom_header_or_sdp_cb;
linphone_core_add_listener(callee_mgr->lc, vtable);
linphone_core_add_listener(caller_mgr->lc, vtable);
-
+
//Caller initates the call with INVITE
// caller params not null
BC_ASSERT_PTR_NOT_NULL((call_caller=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params)));
-
+
BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(call_caller)); /*assert that remote params are NULL when no response is received yet*/
// Wait for Incoming received
@@ -1740,29 +1901,29 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
,initial_callee.number_of_LinphoneCallIncomingReceived+1);
BC_ASSERT_EQUAL(did_receive_call, !callee_test_params.sdp_simulate_error, int, "%d");
-
+
linphone_call_params_unref(caller_params);
-
+
sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal);
sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal);
-
+
// Wait for Outgoing Progress
if (linphone_core_get_calls_nb(callee_mgr->lc)<=1)
BC_ASSERT_TRUE(linphone_core_inc_invite_pending(callee_mgr->lc));
BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d");
-
+
LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,call_callee);
ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params));
linphone_core_accept_call_with_params(callee_mgr->lc,call_callee,default_params);
linphone_call_params_unref(default_params);
-
+
BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1));
BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1));
-
+
result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000)
&&
wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000);
@@ -1776,9 +1937,9 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
linphone_core_update_call(caller_mgr->lc, call_caller, caller_params);
linphone_call_params_unref(caller_params);
-
+
end_call(caller_mgr, callee_mgr);
-
+
linphone_core_manager_destroy(callee_mgr);
linphone_core_manager_destroy(caller_mgr);
}
@@ -1787,17 +1948,17 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
static void call_callee_with_custom_header_or_sdp_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) {
-
-
+
+
const char *value;
if (cstate == LinphoneCallOutgoingInit){
LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_params(call));
linphone_call_params_add_custom_sdp_attribute(params, "working", "maybe");
linphone_call_set_params(call, params);
linphone_call_params_unref(params);
-
+
}
-
+
else if (cstate == LinphoneCallIncomingReceived){
const LinphoneCallParams *tparams = linphone_call_get_remote_params(call);
LinphoneCallParams *params = linphone_call_params_copy(tparams);
@@ -1806,7 +1967,7 @@ static void call_callee_with_custom_header_or_sdp_cb(LinphoneCore *lc, LinphoneC
if (value) BC_ASSERT_STRING_EQUAL(value, "maybe");
linphone_call_set_params(call, params);
linphone_call_params_unref(params);
-
+
}
}
@@ -1818,60 +1979,60 @@ static void call_callee_with_custom_header_or_sdp_attributes(void) {
LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
LinphoneCall *call_caller = NULL, *call_callee = NULL;
LinphoneCallParams *callee_params, *caller_params ;
-
+
LinphoneCoreVTable *vtable;
const char *value;
LinphoneCallTestParams caller_test_params = {0};
LinphoneCallTestParams callee_test_params = {0};
-
+
stats initial_caller=caller_mgr->stat;
stats initial_callee=callee_mgr->stat;
bool_t did_receive_call;
const LinphoneCallParams *caller_remote_params;
-
+
caller_params = linphone_core_create_call_params(caller_mgr->lc, NULL);
-
+
callee_test_params.base = NULL;
caller_test_params.base = NULL;
-
+
/* TODO: This should be handled correctly inside the liblinphone library but meanwhile handle this here. */
linphone_core_manager_wait_for_stun_resolution(caller_mgr);
linphone_core_manager_wait_for_stun_resolution(callee_mgr);
-
+
setup_sdp_handling(&caller_test_params, caller_mgr);
setup_sdp_handling(&callee_test_params, callee_mgr);
-
+
// Assign dedicated callback to vtable for caller and callee
vtable = linphone_core_v_table_new();
vtable->call_state_changed = call_callee_with_custom_header_or_sdp_cb;
linphone_core_add_listener(callee_mgr->lc, vtable);
linphone_core_add_listener(caller_mgr->lc, vtable);
-
+
//Caller initates the call with INVITE
// caller params not null
BC_ASSERT_PTR_NOT_NULL((call_caller=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params)));
-
+
BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(call_caller)); /*assert that remote params are NULL when no response is received yet*/
-
+
// Wait for Incoming received
did_receive_call = wait_for(callee_mgr->lc
,caller_mgr->lc
,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
,initial_callee.number_of_LinphoneCallIncomingReceived+1);
BC_ASSERT_EQUAL(did_receive_call, !callee_test_params.sdp_simulate_error, int, "%d");
-
-
-
+
+
+
sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal);
sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal);
-
+
// Wait for Outgoing Progress
if (linphone_core_get_calls_nb(callee_mgr->lc)<=1)
BC_ASSERT_TRUE(linphone_core_inc_invite_pending(callee_mgr->lc));
BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d");
-
-
+
+
//Create callee params with custom header and custom SDP
@@ -1882,17 +2043,17 @@ static void call_callee_with_custom_header_or_sdp_attributes(void) {
ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(callee_params));
linphone_core_accept_call_with_params(callee_mgr->lc,call_callee,callee_params);
linphone_call_params_unref(callee_params);
-
-
+
+
BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1));
BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1));
-
+
result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000)
&&
wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000);
-
+
BC_ASSERT_TRUE(result);
-
+
caller_remote_params = linphone_call_get_remote_params(call_caller);
value = linphone_call_params_get_custom_sdp_attribute(caller_remote_params, "working");
BC_ASSERT_PTR_NOT_NULL(value);
@@ -1904,7 +2065,7 @@ static void call_callee_with_custom_header_or_sdp_attributes(void) {
linphone_call_params_unref(caller_params);
end_call(caller_mgr, callee_mgr);
-
+
linphone_core_manager_destroy(callee_mgr);
linphone_core_manager_destroy(caller_mgr);
}
@@ -2221,9 +2382,9 @@ static void audio_call_with_ice_no_matching_audio_codecs(void) {
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallError, 1, 6000));
BC_ASSERT_EQUAL(linphone_call_get_reason(out_call), LinphoneReasonNotAcceptable, int, "%d");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d");
-
+
logs = linphone_core_get_call_logs(pauline->lc);
-
+
BC_ASSERT_EQUAL(bctbx_list_size(logs), 1, int, "%d");
if (logs){
const LinphoneErrorInfo *ei;
@@ -2643,9 +2804,9 @@ static void _call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enab
}
linphone_core_set_video_device(pauline->lc,liblinphone_tester_mire_id);
linphone_core_set_video_device(marie->lc,liblinphone_tester_mire_id);
-
+
if (plays_nothing){
- /*This case was for trying to replicate an issue because
+ /*This case was for trying to replicate an issue because
* zrtp_iterate() was only called when packets are received, which
* creates a big problem because no retransmission of HELLO packet will occur
* if the remote sends nothing.
@@ -2887,7 +3048,7 @@ static void early_media_call_with_ringing_base(bool_t network_change){
BC_ASSERT_TRUE(marie_call->all_muted);
liblinphone_tester_check_rtcp(marie, pauline);
-
+
/* this is a hack to simulate an incoming OK with a different IP address
* in the 'c' SDP field. */
if (network_change) {
@@ -3336,7 +3497,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user
((VTableReference*)(marie->lc->vtable_refs->data))->cbs->vtable->auth_info_requested=NULL;
linphone_core_add_auth_info(marie->lc,wrong_auth_info);
}
-
+
BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(marie->lc,marie->identity));
@@ -3400,6 +3561,7 @@ void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, bctbx_l
break;
case LinphoneMediaDirectionRecvOnly:
BC_ASSERT_LOWER((int)stats->upload_bandwidth, 5, int, "%i");
+ BCTBX_NO_BREAK; /*intentionally no break*/
case LinphoneMediaDirectionSendRecv:
expected_recv_iframe = 1;
break;
@@ -3705,7 +3867,7 @@ static void incoming_invite_with_invalid_sdp(void) {
BC_ASSERT_EQUAL(caller->stat.number_of_LinphoneCallError,1, int, "%d");
/*call will be drop before presented to the application, because it is invalid*/
BC_ASSERT_EQUAL(callee->stat.number_of_LinphoneCallIncomingReceived,0, int, "%d");
-
+
logs = linphone_core_get_call_logs(callee->lc);
BC_ASSERT_EQUAL(bctbx_list_size(logs), 1, int, "%i");
if (logs){
@@ -3811,7 +3973,7 @@ void early_media_without_sdp_in_200_base( bool_t use_video, bool_t use_ice ){
lcs = bctbx_list_append(lcs,pauline->lc);
if (use_ice){
linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce);
- /* We need RTP symmetric because ICE will put the STUN address in the C line, and no relay is made in this
+ /* We need RTP symmetric because ICE will put the STUN address in the C line, and no relay is made in this
* scenario.*/
lp_config_set_int(linphone_core_get_config(pauline->lc), "rtp", "symmetric", 1);
}
@@ -4664,7 +4826,7 @@ static void call_record_with_custom_rtp_modifier(void) {
static void recovered_call_on_network_switch_in_early_state(LinphoneCoreManager* callerMgr) {
const LinphoneCallParams *remote_params;
LinphoneCall *incoming_call;
-
+
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
linphone_core_invite_address(callerMgr->lc, pauline->identity);
@@ -4693,7 +4855,7 @@ static void recovered_call_on_network_switch_in_early_state(LinphoneCoreManager*
BC_ASSERT_TRUE(wait_for(callerMgr->lc, pauline->lc, &callerMgr->stat.number_of_LinphoneCallReleased, 1));
BC_ASSERT_TRUE(wait_for(callerMgr->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
end:
-
+
linphone_core_manager_destroy(pauline);
}
static void recovered_call_on_network_switch_in_early_state_1(void) {
@@ -5125,7 +5287,7 @@ static void call_with_network_switch_no_recovery(void){
lcs = bctbx_list_append(lcs, marie->lc);
lcs = bctbx_list_append(lcs, pauline->lc);
-
+
linphone_core_set_nortp_timeout(marie->lc, 50000);
BC_ASSERT_TRUE((call_ok=call_with_params(pauline, marie, pauline_params, NULL)));
@@ -5141,14 +5303,14 @@ static void call_with_network_switch_no_recovery(void){
* We have to wait 32 seconds so that the BYE transaction is terminated, and dialog removed.
* This is the condition to receive a 481 when marie sends the reINVITE.*/
wait_for_list(lcs, NULL, 0, 32500);
-
+
/*marie will reconnect, register, and send an automatic reINVITE to try to repair the call*/
linphone_core_set_network_reachable(marie->lc, TRUE);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 2));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallUpdating, 1));
/*This reINVITE should of course fail, so marie's call should be terminated.*/
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
-
+
end:
if (pauline_params) {
linphone_call_params_unref(pauline_params);
@@ -5692,18 +5854,18 @@ static void call_with_encryption_mandatory(bool_t caller_has_encryption_mandator
LinphoneCallStats *marie_stats, *pauline_stats;
/*marie doesn't support ZRTP at all*/
marie->lc->zrtp_not_available_simulation=1;
-
+
/*pauline requests encryption to be mandatory*/
linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionZRTP);
linphone_core_set_media_encryption_mandatory(pauline->lc, TRUE);
-
+
if (!caller_has_encryption_mandatory){
if (!BC_ASSERT_TRUE(quick_call(marie, pauline))) goto end;
}else{
if (!BC_ASSERT_TRUE(quick_call(pauline, marie))) goto end;
}
wait_for_until(pauline->lc, marie->lc, NULL, 0, 2000);
-
+
/*assert that no RTP packets have been sent or received by Pauline*/
/*testing packet_sent doesn't work, because packets dropped by the transport layer are counted as if they were sent.*/
#if 0
@@ -5735,11 +5897,11 @@ static void v6_to_v4_call_without_relay(void){
LinphoneCoreManager* marie;
LinphoneCoreManager* pauline;
bctbx_list_t *lcs = NULL;
-
+
if (liblinphone_tester_ipv4_available() && liblinphone_tester_ipv6_available()){
marie = linphone_core_manager_new("marie_rc");
pauline = linphone_core_manager_new2("pauline_tcp_rc", FALSE);
-
+
lcs = bctbx_list_append(lcs, marie->lc);
lcs = bctbx_list_append(lcs, pauline->lc);
linphone_core_enable_ipv6(pauline->lc, FALSE);
@@ -5757,7 +5919,7 @@ static void v6_to_v4_call_without_relay(void){
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
bctbx_list_free(lcs);
-
+
}else ms_warning("Test skipped, dual stack not available");
}
@@ -5855,17 +6017,17 @@ static void call_with_network_reachable_down_in_callback(void){
LinphoneCoreManager* marie;
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
LinphoneCall *call;
-
+
linphone_core_cbs_set_call_state_changed(cbs, my_call_state_changed_cb);
-
+
marie = linphone_core_manager_new("laure_rc_udp");
-
+
linphone_core_add_callbacks(marie->lc, cbs);
-
+
call = linphone_core_invite(marie->lc, "inexistant_username_xbfuuuf");
BC_ASSERT_PTR_NOT_NULL(call);
BC_ASSERT_TRUE(wait_for(marie->lc, NULL, &marie->stat.number_of_LinphoneCallError, 1));
-
+
linphone_core_cbs_unref(cbs);
linphone_core_manager_destroy(marie);
}
@@ -6017,7 +6179,10 @@ test_t call_tests[] = {
TEST_NO_TAG("Call from plain RTP to ZRTP mandatory should be silent", call_from_plain_rtp_to_zrtp),
TEST_NO_TAG("Call ZRTP mandatory to plain RTP should be silent", call_from_zrtp_to_plain_rtp),
TEST_NO_TAG("Call with network reachable down in callback", call_with_network_reachable_down_in_callback),
- TEST_NO_TAG("Call terminated with reason", terminate_call_with_error)
+ TEST_NO_TAG("Call terminated with reason", terminate_call_with_error),
+ TEST_NO_TAG("Call cancelled with reason", cancel_call_with_error),
+ TEST_NO_TAG("Call accepted, other ringing device receive CANCEL with reason", cancel_other_device_after_accept),
+ TEST_NO_TAG("Call declined, other ringing device receive CANCEL with reason", cancel_other_device_after_decline)
};
test_suite_t call_test_suite = {"Single Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c
index 57a401d29..1c987a249 100644
--- a/tester/flexisip_tester.c
+++ b/tester/flexisip_tester.c
@@ -22,6 +22,12 @@
#include "private.h"
#include "liblinphone_tester.h"
+static void setPublish(LinphoneProxyConfig * proxy_config, bool_t enable) {
+ linphone_proxy_config_edit(proxy_config);
+ linphone_proxy_config_enable_publish(proxy_config, enable);
+ linphone_proxy_config_done(proxy_config);
+}
+
static void subscribe_forking(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
@@ -724,7 +730,7 @@ static void _call_with_ipv6(bool_t caller_with_ipv6, bool_t callee_with_ipv6) {
marie = linphone_core_manager_new2( "marie_rc", FALSE);
linphone_core_enable_ipv6(marie->lc, caller_with_ipv6);
linphone_core_manager_start(marie, TRUE);
-
+
pauline = linphone_core_manager_new2( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", FALSE);
linphone_core_enable_ipv6(pauline->lc, callee_with_ipv6);
linphone_core_manager_start(pauline, TRUE);
@@ -740,13 +746,13 @@ static void _call_with_ipv6(bool_t caller_with_ipv6, bool_t callee_with_ipv6) {
/*check that the remote contact is IPv6*/
BC_ASSERT_EQUAL(is_remote_contact_ipv6(pauline_call), caller_with_ipv6, int, "%i");
BC_ASSERT_EQUAL(is_remote_contact_ipv6(marie_call), callee_with_ipv6, int, "%i");
-
+
/*check that the RTP destinations are IPv6 (flexisip should propose an IPv6 relay for parties with IPv6)*/
BC_ASSERT_EQUAL(is_sending_ipv6(marie_call->sessions[0].rtp_session, FALSE), caller_with_ipv6, int, "%i");
BC_ASSERT_EQUAL(is_sending_ipv6(marie_call->sessions[0].rtp_session, TRUE), caller_with_ipv6, int, "%i");
BC_ASSERT_EQUAL(is_sending_ipv6(pauline_call->sessions[0].rtp_session, FALSE), callee_with_ipv6, int, "%i");
BC_ASSERT_EQUAL(is_sending_ipv6(pauline_call->sessions[0].rtp_session, TRUE), callee_with_ipv6, int, "%i");
-
+
}
liblinphone_tester_check_rtcp(marie,pauline);
@@ -1053,16 +1059,11 @@ static void test_subscribe_notify_with_sipp_publisher_double_publish(void) {
static void test_publish_unpublish(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
- LinphoneProxyConfig* proxy;
+ LinphoneProxyConfig* proxy = linphone_core_get_default_proxy_config(marie->lc);
- proxy = linphone_core_get_default_proxy_config(marie->lc);
- linphone_proxy_config_edit(proxy);
- linphone_proxy_config_enable_publish(proxy,TRUE);
- linphone_proxy_config_done(proxy);
+ setPublish(proxy, TRUE);
wait_for(marie->lc, NULL, NULL, 0);
- linphone_proxy_config_edit(proxy);
- linphone_proxy_config_enable_publish(proxy,FALSE);
- linphone_proxy_config_done(proxy);
+ setPublish(proxy, FALSE);
wait_for(marie->lc, NULL, NULL, 0);
linphone_core_manager_destroy(marie);
}
@@ -1090,7 +1091,6 @@ static void test_list_subscribe (void) {
char * subscribe_content = ms_strdup_printf(list,pauline_uri,laure_uri);
LinphoneContent* content = linphone_core_create_content(marie->lc);
LinphoneAddress *list_name = linphone_address_new("sip:mescops@sip.example.org");
- LinphoneProxyConfig* proxy_config;
int dummy=0;
ms_free(pauline_uri);
@@ -1119,17 +1119,11 @@ static void test_list_subscribe (void) {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));
/*dummy wait to avoid derred notify*/
wait_for_list(lcs,&dummy,1,2000);
- proxy_config = linphone_core_get_default_proxy_config(pauline->lc);
- linphone_proxy_config_edit(proxy_config);
- linphone_proxy_config_enable_publish(proxy_config,TRUE);
- linphone_proxy_config_done(proxy_config);
+ setPublish(linphone_core_get_default_proxy_config(pauline->lc), TRUE);
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,2,5000));
- proxy_config = linphone_core_get_default_proxy_config(laure->lc);
- linphone_proxy_config_edit(proxy_config);
- linphone_proxy_config_enable_publish(proxy_config,TRUE);
- linphone_proxy_config_done(proxy_config);
+ setPublish(linphone_core_get_default_proxy_config(laure->lc), TRUE);
/*make sure notify is not sent "imadiatly but defered*/
BC_ASSERT_FALSE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,3,1000));
@@ -1172,20 +1166,20 @@ static void test_subscribe_on_wrong_dialog(void) {
static void test_list_subscribe_wrong_body(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
-
+
LinphoneEvent *lev;
LinphoneAddress *sub_addr = linphone_address_new("sip:rls@sip.example.com");
-
+
lev=linphone_core_create_subscribe(marie->lc,sub_addr,"presence",60);
-
+
linphone_event_add_custom_header(lev,"Supported","eventlist");
linphone_event_add_custom_header(lev,"Accept","application/pidf+xml, application/rlmi+xml");
linphone_event_add_custom_header(lev,"Content-Disposition", "recipient-list");
linphone_event_add_custom_header(lev,"Require", "recipient-list-subscribe");
linphone_event_add_custom_header(lev,"Content-type", "application/resource-lists+xml");
-
+
linphone_event_send_subscribe(lev,NULL);
-
+
BC_ASSERT_TRUE(wait_for_until(marie->lc,NULL,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000));
BC_ASSERT_FALSE(wait_for_until(marie->lc,NULL,&marie->stat.number_of_LinphoneSubscriptionActive,1,2000));
@@ -1200,16 +1194,16 @@ static void redis_publish_subscribe(void) {
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
LinphoneCoreManager* marie2 = NULL;
LinphoneAddress *marie_identity = linphone_address_ref(marie->identity);
-
+
linphone_core_set_network_reachable(marie->lc, FALSE);
linphone_core_manager_destroy(marie);
-
+
linphone_core_invite_address(pauline->lc, marie_identity);
BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneCallOutgoingProgress, 1, 3000));
-
+
marie2 = linphone_core_manager_new("marie2_rc");
BC_ASSERT_TRUE(wait_for_until(marie2->lc, NULL, &marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 3000));
-
+
linphone_address_unref(marie_identity);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie2);
@@ -1218,10 +1212,10 @@ static void redis_publish_subscribe(void) {
static void tls_authentication_requested_good(LinphoneCore *lc, LinphoneAuthInfo *auth_info, LinphoneAuthMethod method) {
if (method == LinphoneAuthTls){
-
+
char *cert = bc_tester_res("certificates/client/cert2.pem");
char *key = bc_tester_res("certificates/client/key2.pem");
-
+
linphone_auth_info_set_tls_cert_path(auth_info, cert);
linphone_auth_info_set_tls_key_path(auth_info, key);
linphone_core_add_auth_info(lc, auth_info);
@@ -1232,10 +1226,10 @@ static void tls_authentication_requested_good(LinphoneCore *lc, LinphoneAuthInfo
static void tls_authentication_requested_bad(LinphoneCore *lc, LinphoneAuthInfo *auth_info, LinphoneAuthMethod method) {
if (method == LinphoneAuthTls){
-
+
char *cert = bc_tester_res("certificates/client/cert2-signed-by-other-ca.pem");
char *key = bc_tester_res("certificates/client/key2.pem");
-
+
linphone_auth_info_set_tls_cert_path(auth_info, cert);
linphone_auth_info_set_tls_key_path(auth_info, key);
linphone_core_add_auth_info(lc, auth_info);
@@ -1255,7 +1249,7 @@ static void tls_client_auth_try_register(const char *identity, bool_t with_good_
linphone_core_add_callbacks(lcm->lc, cbs);
linphone_core_cbs_unref(cbs);
cfg = linphone_core_create_proxy_config(lcm->lc);
-
+
linphone_proxy_config_set_server_addr(cfg, "sip:sip2.linphone.org:5063;transport=tls");
linphone_proxy_config_enable_register(cfg, TRUE);
linphone_proxy_config_set_identity(cfg, identity);
@@ -1272,7 +1266,7 @@ static void tls_client_auth_try_register(const char *identity, bool_t with_good_
if (with_good_cert) BC_ASSERT_EQUAL(lcm->stat.number_of_auth_info_requested,2, int, "%d");
else BC_ASSERT_EQUAL(lcm->stat.number_of_auth_info_requested,1, int, "%d");
}
-
+
linphone_proxy_config_unref(cfg);
linphone_core_manager_destroy(lcm);
}
@@ -1322,7 +1316,7 @@ void transcoder_tester(void) {
/*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/
linphone_core_use_files(marie->lc,TRUE);
linphone_core_set_play_file(marie->lc,NULL);
-
+
/*callee is recording and plays file*/
linphone_core_use_files(pauline->lc,TRUE);
linphone_core_set_play_file(pauline->lc,NULL);
@@ -1362,6 +1356,30 @@ end:
ms_free(hellopath);
}
+void test_removing_old_tport(void) {
+ bctbx_list_t* lcs;
+ LinphoneCoreManager* marie2;
+ LinphoneCoreManager* marie1 = linphone_core_manager_new("marie_rc");
+ lcs=bctbx_list_append(NULL,marie1->lc);
+
+ BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneRegistrationOk,1,5000));
+
+ marie2 = ms_new0(LinphoneCoreManager, 1);
+ linphone_core_manager_init(marie2, "marie_rc", NULL);
+ sal_set_uuid(marie2->lc->sal, linphone_config_get_string(linphone_core_get_config(marie1->lc),"misc", "uuid", "0"));
+ linphone_core_manager_start(marie2, TRUE);
+ lcs=bctbx_list_append(lcs, marie2->lc);
+ linphone_core_refresh_registers(marie2->lc);
+
+ BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneRegistrationOk,1,5000));
+
+ BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneRegistrationProgress,2,5000));
+
+ linphone_core_manager_destroy(marie1);
+ linphone_core_manager_destroy(marie2);
+ bctbx_list_free(lcs);
+}
+
test_t flexisip_tests[] = {
TEST_ONE_TAG("Subscribe forking", subscribe_forking, "LeaksMemory"),
TEST_NO_TAG("Message forking", message_forking),
@@ -1398,7 +1416,8 @@ test_t flexisip_tests[] = {
TEST_ONE_TAG("Redis Publish/subscribe", redis_publish_subscribe, "Skip"),
TEST_NO_TAG("TLS authentication - client rejected due to CN mismatch", tls_client_auth_bad_certificate_cn),
TEST_NO_TAG("TLS authentication - client rejected due to unrecognized certificate chain", tls_client_auth_bad_certificate),
- TEST_NO_TAG("Transcoder", transcoder_tester)
+ TEST_NO_TAG("Transcoder", transcoder_tester),
+ TEST_NO_TAG("Removing old tport on flexisip for the same client", test_removing_old_tport)
};
diff --git a/tester/message_tester.c b/tester/message_tester.c
index c5ee54ef4..3df2e4d0b 100644
--- a/tester/message_tester.c
+++ b/tester/message_tester.c
@@ -22,6 +22,7 @@
#include "private.h"
#include "liblinphone_tester.h"
#include "lime.h"
+#include "bctoolbox/crypto.h"
#ifdef SQLITE_STORAGE_ENABLED
#include
@@ -2295,26 +2296,19 @@ void text_message_with_custom_content_type_and_lime(void) {
_text_message_with_custom_content_type(TRUE);
}
-char* xor(char* message, char* key) {
- size_t messagelen = strlen(message);
- size_t keylen = strlen(key);
- char* encrypted = (char *)ms_malloc(messagelen+1);
- int i;
- for(i = 0; i < (int)messagelen; i++) {
- encrypted[i] = message[i] ^ key[i % keylen];
- }
- encrypted[messagelen] = '\0';
-
- return encrypted;
-}
-
-int xor_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
- char *new_content_type = "cipher/xor";
+static int im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
if (msg->content_type) {
- if (strcmp(msg->content_type, new_content_type) == 0) {
- msg->message = xor(msg->message, "SuperSecretXorKey");
- msg->content_type = ms_strdup("text/plain");
+ if (strcmp(msg->content_type, "cipher/b64") == 0) {
+ size_t b64Size = 0;
+ unsigned char *output;
+ bctbx_base64_decode(NULL, &b64Size, (unsigned char *)msg->message, strlen(msg->message));
+ output = (unsigned char *)ms_malloc(b64Size+1),
+ bctbx_base64_decode(output, &b64Size, (unsigned char *)msg->message, strlen(msg->message));
+ ms_free (msg->message);
+ output[b64Size] = '\0';
+ msg->message = (char *)output;
+ linphone_chat_message_set_content_type(msg, "text/plain");
return 0;
} else if (strcmp(msg->content_type, "text/plain") == 0) {
return -1; // Not encrypted, nothing to do
@@ -2325,14 +2319,23 @@ int xor_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEng
return 500;
}
-int xor_im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
- char *new_content_type = "cipher/xor";
- msg->message = xor(msg->message, "SuperSecretXorKey");
- msg->content_type = ms_strdup(new_content_type);
- return 0;
+static int im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
+ if (strcmp(msg->content_type,"text/plain") == 0) {
+ size_t b64Size = 0;
+ unsigned char *output;
+ bctbx_base64_encode(NULL, &b64Size, (unsigned char *)msg->message, strlen(msg->message));
+ output = (unsigned char *)ms_malloc0(b64Size+1),
+ bctbx_base64_encode(output, &b64Size, (unsigned char *)msg->message, strlen(msg->message));
+ ms_free (msg->message);
+ output[b64Size] = '\0';
+ msg->message = (char *)output;
+ linphone_chat_message_set_content_type(msg, "cipher/b64");
+ return 0;
+ }
+ return -1;
}
-void im_encryption_engine_xor(void) {
+void im_encryption_engine_b64(void) {
LinphoneChatMessage *chat_msg = NULL;
LinphoneChatRoom* chat_room = NULL;
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
@@ -2342,10 +2345,10 @@ void im_encryption_engine_xor(void) {
LinphoneImEncryptionEngine *pauline_imee = linphone_im_encryption_engine_new(pauline->lc);
LinphoneImEncryptionEngineCbs *pauline_cbs = linphone_im_encryption_engine_get_callbacks(pauline_imee);
- linphone_im_encryption_engine_cbs_set_process_incoming_message(marie_cbs, xor_im_encryption_engine_process_incoming_message_cb);
- linphone_im_encryption_engine_cbs_set_process_outgoing_message(marie_cbs, xor_im_encryption_engine_process_outgoing_message_cb);
- linphone_im_encryption_engine_cbs_set_process_incoming_message(pauline_cbs, xor_im_encryption_engine_process_incoming_message_cb);
- linphone_im_encryption_engine_cbs_set_process_outgoing_message(pauline_cbs, xor_im_encryption_engine_process_outgoing_message_cb);
+ linphone_im_encryption_engine_cbs_set_process_incoming_message(marie_cbs, im_encryption_engine_process_incoming_message_cb);
+ linphone_im_encryption_engine_cbs_set_process_outgoing_message(marie_cbs, im_encryption_engine_process_outgoing_message_cb);
+ linphone_im_encryption_engine_cbs_set_process_incoming_message(pauline_cbs, im_encryption_engine_process_incoming_message_cb);
+ linphone_im_encryption_engine_cbs_set_process_outgoing_message(pauline_cbs, im_encryption_engine_process_outgoing_message_cb);
linphone_core_set_im_encryption_engine(marie->lc, marie_imee);
linphone_core_set_im_encryption_engine(pauline->lc, pauline_imee);
@@ -2441,7 +2444,7 @@ test_t message_tests[] = {
#ifdef SQLITE_STORAGE_ENABLED
TEST_ONE_TAG("Text message with custom content-type and lime", text_message_with_custom_content_type_and_lime, "LIME"),
#endif
- TEST_NO_TAG("IM Encryption Engine XOR", im_encryption_engine_xor)
+ TEST_NO_TAG("IM Encryption Engine b64", im_encryption_engine_b64)
};
test_suite_t message_test_suite = {
diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c
index bc901d797..4e8753a55 100644
--- a/tester/presence_server_tester.c
+++ b/tester/presence_server_tester.c
@@ -55,8 +55,8 @@ static void simple(void) {
linphone_core_cbs_unref(callbacks);
lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
- linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
enable_publish(pauline, TRUE);
BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,1));
@@ -74,15 +74,23 @@ static void simple(void) {
}
BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,2));
-
+
+ linphone_friend_invalidate_subscription(f);
+ linphone_friend_enable_subscribes(f, FALSE);
+ wait_for_until(marie->lc, NULL, NULL, 0, 5000);
linphone_friend_unref(f);
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(marie->lc), FALSE);
+ wait_for_until(marie->lc, NULL, NULL, 0, 5000);
+
+ linphone_core_manager_stop(marie);
linphone_core_manager_destroy(marie);
linphone_core_manager_stop(pauline);
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,1,int,"%i");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,2,int,"%i");
linphone_core_manager_destroy(pauline);
- }
+}
static void fast_activity_change(void) {
#if FIX_ME
@@ -93,8 +101,8 @@ static void fast_activity_change(void) {
LinphonePresenceActivity *activity = NULL;
lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
- linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
enable_publish(pauline, TRUE);
linphone_friend_enable_subscribes(f, TRUE);
@@ -146,8 +154,8 @@ static void subscriber_no_longer_reachable(void){
lcs = bctbx_list_append(lcs, pauline1->lc);
lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 80);
- linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
- linphone_core_set_user_agent(pauline1->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
+ linphone_core_set_user_agent(pauline1->lc, "full-presence-support-bypass", NULL);
enable_publish(pauline1, TRUE);
@@ -214,8 +222,8 @@ static void subscribe_with_late_publish(void) {
char* lf_identity;
LinphoneFriend *lf;
- linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
pauline_lp = linphone_core_get_config(pauline->lc);
lf_identity=linphone_address_as_string_uri_only(marie->identity);
lf = linphone_core_create_friend_with_address(pauline->lc,lf_identity);
@@ -262,7 +270,7 @@ static void subscribe_with_late_publish(void) {
/*Expect a notify at publication expiration because marie is no longuer scheduled*/
BC_ASSERT_FALSE(wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityBusy,3,6000));
/*thanks to long term presence we are still online*/
- BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
+ BC_ASSERT_EQUAL(LinphoneStatusAway,linphone_friend_get_status(lf), int, "%d");
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphonePresenceActivityBusy,3,5000));/*re- schedule marie to clean up things*/
@@ -279,7 +287,7 @@ static void subscribe_with_late_publish(void) {
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphonePresenceActivityAppointment,1,5000));
- BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAway, 1, int,"%i");
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAway, 4, int,"%i");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityBreakfast, 0, int,"%i");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAppointment, 1, int,"%i");
@@ -302,9 +310,9 @@ static void test_forked_subscribe_notify_publish(void) {
lcs=bctbx_list_append(lcs,marie->lc);
lcs=bctbx_list_append(lcs,marie->lc);
lcs=bctbx_list_append(lcs,marie2->lc);
- linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
- linphone_core_set_user_agent(marie2->lc, "full-presence-support", NULL);
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
+ linphone_core_set_user_agent(marie2->lc, "full-presence-support-bypass", NULL);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
pauline_lp = linphone_core_get_config(pauline->lc);
@@ -335,7 +343,7 @@ static void test_forked_subscribe_notify_publish(void) {
/*wait for marie status*/
wait_for_list(lcs,&pauline->stat.number_of_LinphonePresenceActivityOnline,3,2000); /*initial + 2 from publish*/
- BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
+ BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityBusy,NULL);
linphone_core_set_presence_model(marie->lc,presence);
@@ -343,7 +351,7 @@ static void test_forked_subscribe_notify_publish(void) {
/*wait for new status*/
wait_for_list(lcs,&pauline->stat.number_of_LinphonePresenceActivityBusy,1,3000);
- BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
+ BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
presence =linphone_presence_model_new_with_activity( LinphonePresenceActivityMeeting,NULL);
@@ -361,8 +369,11 @@ static void test_forked_subscribe_notify_publish(void) {
static void test_presence_list_base(bool_t enable_compression) {
LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
+ linphone_core_set_user_agent(laure->lc, "bypass", NULL);
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(marie->lc, "bypass", NULL);
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "bypass", NULL);
const char *rls_uri = "sip:rls@sip.example.org";
LinphoneFriendList *lfl;
LinphoneFriend *lf;
@@ -488,30 +499,29 @@ static void test_presence_list_base(bool_t enable_compression) {
reset_counters(&marie->stat);
/*keep in mind long terme presence*/
-
- if (!BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphonePresenceActivityOnline, 1, 4000)))
+ if (!BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphonePresenceActivityAway, 1, 4000)))
goto end;
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
/*BC_ASSERT_EQUAL(linphone_presence_activity_get_type(linphone_presence_model_get_activity(linphone_friend_get_presence_model(lf)))
, LinphonePresenceActivityOnline, int, "%d"); fixme, should be LinphonePresenceActivityUnknown*/
- BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
+ BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
- if (!BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphonePresenceActivityOnline, 2, 4000))) goto end;
+ if (!BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphonePresenceActivityAway, 2, 4000))) goto end;
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
- BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
+ BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
/*BC_ASSERT_EQUAL(linphone_presence_activity_get_type(linphone_presence_model_get_activity(linphone_friend_get_presence_model(lf)))
, LinphonePresenceActivityOnline, int, "%d"); fixme, should be LinphonePresenceActivityUnknown*/
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity);
- BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
+ BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
/*BC_ASSERT_EQUAL(linphone_presence_activity_get_type(linphone_presence_model_get_activity(linphone_friend_get_presence_model(lf)))
, LinphonePresenceActivityOnline, int, "%d"); fixme, should be LinphonePresenceActivityUnknown*/
- if (!BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphonePresenceActivityOnline, 1, 4000))) goto end;
+ if (!BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphonePresenceActivityAway, 1, 4000))) goto end;
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity);
- BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
+ BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
/*BC_ASSERT_EQUAL(linphone_presence_activity_get_type(linphone_presence_model_get_activity(linphone_friend_get_presence_model(lf)))
, LinphonePresenceActivityOnline, int, "%d"); fixme, should be LinphonePresenceActivityUnknown*/
@@ -533,7 +543,9 @@ static void test_presence_list_without_compression(void) {
#if 0
static void test_presence_list_subscribe_before_publish(void) {
LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
+ linphone_core_set_user_agent(laure->lc, "bypass", NULL);
LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "bypass", NULL);
const char *rls_uri = "sip:rls@sip.example.org";
LinphoneFriendList *lfl;
LinphoneFriend *lf;
@@ -589,6 +601,7 @@ static void test_presence_list_subscribe_before_publish(void) {
static void test_presence_list_subscription_expire_for_unknown(void) {
LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
+ linphone_core_set_user_agent(laure->lc, "bypass", NULL);
const char *rls_uri = "sip:rls@sip.example.org";
LinphoneFriendList *lfl;
LinphoneFriend *lf;
@@ -612,7 +625,9 @@ static void test_presence_list_subscription_expire_for_unknown(void) {
static void test_presence_list_subscribe_with_error(bool_t io_error) {
LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(laure->lc, "bypass", NULL);
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "bypass", NULL);
const char *rls_uri = "sip:rls@sip.example.org";
LinphoneFriendList *lfl;
LinphoneFriend *lf;
@@ -677,7 +692,7 @@ static void test_presence_list_subscribe_with_error(bool_t io_error) {
/*a new subscribe should be sent */
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 3, 9000)); /* give time for subscription to recover to avoid to receive 491 Request pending*/
-
+ reset_counters(&laure->stat);
presence = linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityAway, NULL);
linphone_core_set_presence_model(pauline->lc, presence);
linphone_presence_model_unref(presence);
@@ -700,7 +715,9 @@ static void presence_list_subscribe_io_error(void) {
static void presence_list_subscribe_network_changes(void) {
LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(laure->lc, "bypass", NULL);
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "bypass", NULL);
const char *rls_uri = "sip:rls@sip.example.org";
LinphoneFriendList *lfl;
LinphoneFriend *lf;
@@ -777,8 +794,8 @@ static void long_term_presence_base(const char* addr, bool_t exist, const char*
const LinphonePresenceModel* model;
char *presence_contact;
int *presence;
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
friend2=linphone_core_create_friend_with_address(pauline->lc,addr);
linphone_friend_edit(friend2);
@@ -786,7 +803,7 @@ static void long_term_presence_base(const char* addr, bool_t exist, const char*
linphone_friend_done(friend2);
linphone_core_add_friend(pauline->lc,friend2);
- presence = exist ? &pauline->stat.number_of_LinphonePresenceActivityOnline : &pauline->stat.number_of_LinphonePresenceActivityOffline;
+ presence = exist ? &pauline->stat.number_of_LinphonePresenceActivityAway : &pauline->stat.number_of_LinphonePresenceActivityOffline;
BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,presence,1));
BC_ASSERT_EQUAL(*presence, 1, int, "%d");
model = linphone_friend_get_presence_model(friend2);
@@ -830,6 +847,7 @@ static const char* random_phone_number(void) {
static void long_term_presence_phone_alias2(void) {
LinphoneCoreManager *marie = linphone_core_manager_new3("marie_rc", TRUE, random_phone_number());
+ linphone_core_set_user_agent(marie->lc, "bypass", NULL);
char * identity = linphone_address_as_string_uri_only(marie->identity);
LinphoneAddress * phone_addr = linphone_core_interpret_url(marie->lc, marie->phone_alias);
char *phone_addr_uri = linphone_address_as_string(phone_addr);
@@ -850,7 +868,8 @@ static void long_term_presence_list(void) {
const char *nationnal_phone_number = "0123456789";
LinphoneProxyConfig * pauline_proxy_config;
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "bypass", NULL);
enable_publish(pauline, FALSE);
enable_deflate_content_encoding(pauline, FALSE);
@@ -900,14 +919,15 @@ static void long_term_presence_list(void) {
static void long_term_presence_with_e164_phone_without_sip(void) {
if (linphone_core_vcard_supported()){
LinphoneCoreManager *marie = linphone_core_manager_new3("marie_rc", TRUE, random_phone_number());
+ linphone_core_set_user_agent(marie->lc, "bypass", NULL);
char * identity = linphone_address_as_string_uri_only(marie->identity);
LinphoneAddress * phone_addr = linphone_core_interpret_url(marie->lc, marie->phone_alias);
char *phone_addr_uri = linphone_address_as_string(phone_addr);
LinphoneFriend* friend2;
char *presence_contact;
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
friend2=linphone_core_create_friend(pauline->lc);
linphone_friend_add_phone_number(friend2, marie->phone_alias);
@@ -917,8 +937,8 @@ static void long_term_presence_with_e164_phone_without_sip(void) {
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), TRUE);
linphone_core_refresh_registers(pauline->lc);
- BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphonePresenceActivityOnline,1));
- BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityOnline, 1, int, "%d");
+ BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphonePresenceActivityAway,1));
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAway, 1, int, "%d");
BC_ASSERT_EQUAL(linphone_presence_model_get_basic_status(linphone_friend_get_presence_model(friend2)), LinphonePresenceBasicStatusOpen, int, "%d");
if(BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_presence_model(friend2))) {
presence_contact = linphone_presence_model_get_contact(linphone_friend_get_presence_model(friend2));
@@ -961,10 +981,11 @@ static void long_term_presence_with_phone_without_sip(void) {
ms_message("Phone number is %s, e164 is %s", phone, e164);
marie = linphone_core_manager_new3("marie_rc", TRUE, e164);
+ linphone_core_set_user_agent(marie->lc, "bypass", NULL);
identity = linphone_address_as_string_uri_only(marie->identity);
- LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
friend2=linphone_core_create_friend(pauline->lc);
linphone_friend_add_phone_number(friend2, phone);
@@ -975,7 +996,7 @@ static void long_term_presence_with_phone_without_sip(void) {
linphone_core_refresh_registers(pauline->lc);
/*because phone is not normalized*/
- BC_ASSERT_FALSE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphonePresenceActivityOnline,1,2000));
+ BC_ASSERT_FALSE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphonePresenceActivityAway,1,2000));
/*know adding ccc to proxy config*/
proxy_config = linphone_core_get_default_proxy_config(pauline->lc);
@@ -989,8 +1010,8 @@ static void long_term_presence_with_phone_without_sip(void) {
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), TRUE);
- BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphonePresenceActivityOnline,1));
- BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityOnline, 1, int, "%d");
+ BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphonePresenceActivityAway,1));
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAway, 1, int, "%d");
BC_ASSERT_EQUAL(linphone_presence_model_get_basic_status(linphone_friend_get_presence_model(friend2)), LinphonePresenceBasicStatusOpen, int, "%d");
if(BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_presence_model(friend2))) {
presence_contact = linphone_presence_model_get_contact(linphone_friend_get_presence_model(friend2));
@@ -1038,10 +1059,9 @@ static void long_term_presence_with_crossed_references(void) {
ms_message("Pauline's phone number is %s", e164_pauline=generate_random_e164_phone_from_dial_plan(dialPlan));
ms_message("Laure's phone number is %s", e164_laure=generate_random_e164_phone_from_dial_plan(dialPlan));
-
/*pauline has marie as friend*/
- LinphoneCoreManager *pauline = linphone_core_manager_new3("pauline_rc",TRUE,e164_pauline);
- linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ LinphoneCoreManager *pauline = linphone_core_manager_new3("pauline_tcp_rc",TRUE,e164_pauline);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
friend2=linphone_core_create_friend(pauline->lc);
linphone_friend_add_phone_number(friend2, e164_marie);
linphone_core_add_friend(pauline->lc,friend2);
@@ -1050,10 +1070,9 @@ static void long_term_presence_with_crossed_references(void) {
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), TRUE);
linphone_core_refresh_registers(pauline->lc);
-
//Laure has marie as friend
LinphoneCoreManager *laure = linphone_core_manager_new3("laure_tcp_rc",TRUE,e164_laure);
- linphone_core_set_user_agent(laure->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(laure->lc, "full-presence-support-bypass", NULL);
friend2=linphone_core_create_friend(laure->lc);
linphone_friend_add_phone_number(friend2, e164_marie);
linphone_core_add_friend(laure->lc,friend2);
@@ -1062,13 +1081,13 @@ static void long_term_presence_with_crossed_references(void) {
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(laure->lc), TRUE);
linphone_core_refresh_registers(laure->lc);
-
/*because marie is not registered yet*/
- BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&pauline->stat.number_of_LinphonePresenceActivityOnline,1,2000));
- BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&laure->stat.number_of_LinphonePresenceActivityOnline,1,2000));
+ BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&pauline->stat.number_of_LinphonePresenceActivityAway,1,2000));
+ BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&laure->stat.number_of_LinphonePresenceActivityAway,1,2000));
//Now, marie register to the service
LinphoneCoreManager *marie = linphone_core_manager_new3("marie_rc", TRUE, e164_marie);
+ linphone_core_set_user_agent(marie->lc, "bypass", NULL);
friend2=linphone_core_create_friend(marie->lc);
linphone_friend_add_phone_number(friend2, e164_pauline);
linphone_core_add_friend(marie->lc,friend2);
@@ -1078,19 +1097,18 @@ static void long_term_presence_with_crossed_references(void) {
linphone_core_refresh_registers(marie->lc);
//Pauline is already registered so I must be notified very rapidely
- BC_ASSERT_TRUE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePresenceActivityOnline,1,4000));
-
+ BC_ASSERT_TRUE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePresenceActivityAway,1,4000));
//For Pauline and Laure long term presence check was already performed so they will not be notified until new subscription
- BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&laure->stat.number_of_LinphonePresenceActivityOnline,1,4000));
- BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&pauline->stat.number_of_LinphonePresenceActivityOnline,1,4000));
+ BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&laure->stat.number_of_LinphonePresenceActivityAway,1,4000));
+ BC_ASSERT_FALSE(wait_for_until(pauline->lc,laure->lc,&pauline->stat.number_of_LinphonePresenceActivityAway,1,4000));
//re-subscribe to get notification.
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
wait_for_until(pauline->lc, NULL, NULL, 0,2000); /*wait for unsubscribe*/
linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), TRUE);
- BC_ASSERT_TRUE(wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityOnline,1,4000));
+ BC_ASSERT_TRUE(wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityAway,1,4000));
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
@@ -1105,16 +1123,23 @@ static void multiple_publish_aggregation(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
LinphoneCoreManager* pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
- LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
+ LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityVacation, NULL);
LinphonePresenceModel *pauline_presence2 = linphone_presence_model_new_with_activity(LinphonePresenceActivityAway, NULL);
LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline));
+ LinphoneFriend* f2 = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
+ LinphoneFriend* f3 = linphone_core_create_friend_with_address(pauline2->lc, get_identity(marie));
LinphonePresenceActivity *activity = NULL;
LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get());
int nb_act = 0;
int i = 0;
bool_t eq = FALSE;
+ bctbx_list_t *lcs = NULL;
+ lcs = bctbx_list_append(lcs, marie->lc);
+ lcs = bctbx_list_append(lcs, pauline->lc);
+ lcs = bctbx_list_append(lcs, pauline2->lc);
linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed);
+ _linphone_core_add_callbacks(marie->lc, callbacks, TRUE);
_linphone_core_add_callbacks(pauline->lc, callbacks, TRUE);
_linphone_core_add_callbacks(pauline2->lc, callbacks, TRUE);
linphone_core_cbs_unref(callbacks);
@@ -1132,36 +1157,412 @@ static void multiple_publish_aggregation(void) {
linphone_friend_set_inc_subscribe_policy(f,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
linphone_core_add_friend(marie->lc, f);
+ linphone_friend_enable_subscribes(f2, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f2,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline->lc, f2);
+
+ linphone_friend_enable_subscribes(f3, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f3,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline2->lc, f3);
+
linphone_core_set_presence_model(pauline->lc, pauline_presence);
linphone_presence_model_unref(pauline_presence);
linphone_core_set_presence_model(pauline2->lc, pauline_presence2);
linphone_presence_model_unref(pauline_presence2);
- BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityVacation,1));
BC_ASSERT_TRUE(wait_for(marie->lc,pauline2->lc,&marie->stat.number_of_LinphonePresenceActivityAway,1));
nb_act = linphone_presence_model_get_nb_activities(linphone_friend_get_presence_model(f));
BC_ASSERT_EQUAL(nb_act, 2, int, "%d");
for(i = 0; i < nb_act; i++) {
activity = linphone_presence_model_get_nth_activity(linphone_friend_get_presence_model(f),i);
- eq = (linphone_presence_activity_get_type(activity) == LinphonePresenceActivityAway || linphone_presence_activity_get_type(activity) == LinphonePresenceActivityDinner);
+ eq = (linphone_presence_activity_get_type(activity) == LinphonePresenceActivityAway || linphone_presence_activity_get_type(activity) == LinphonePresenceActivityVacation);
BC_ASSERT_TRUE(eq);
}
BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,2));
BC_ASSERT_TRUE(wait_for(marie->lc,pauline2->lc,&pauline2->stat.number_of_LinphonePublishOk,2));
+ linphone_friend_enable_subscribes(f, FALSE);
+ linphone_friend_enable_subscribes(f2, FALSE);
+ linphone_friend_enable_subscribes(f3, FALSE);
+ wait_for_list(lcs,NULL, 0, 5000); // wait for unsubscritptions
linphone_friend_unref(f);
+ linphone_friend_unref(f2);
+ linphone_friend_unref(f3);
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(marie->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline2->lc), FALSE);
+ wait_for_list(lcs,NULL, 0, 5000); // wait for unsubscritptions
+
linphone_core_manager_destroy(marie);
linphone_core_manager_stop(pauline);
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,1,int,"%i");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,2,int,"%i");
linphone_core_manager_destroy(pauline);
+
linphone_core_manager_stop(pauline2);
BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphonePublishCleared,1,int,"%i");
BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphonePublishOk,2,int,"%i");
linphone_core_manager_destroy(pauline2);
+
+ bctbx_list_free(lcs);
+}
+
+static void extended_notify_only_both_side_subscribed(void) {
+ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
+ LinphonePresenceModel *marie_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityTV, NULL);
+ LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline));
+ LinphoneFriend* f2 = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
+ LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get());
+ bctbx_list_t *lcs = NULL;
+ lcs = bctbx_list_append(lcs, marie->lc);
+ lcs = bctbx_list_append(lcs, pauline->lc);
+
+ linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed);
+ _linphone_core_add_callbacks(marie->lc, callbacks, TRUE);
+ _linphone_core_add_callbacks(pauline->lc, callbacks, TRUE);
+ linphone_core_cbs_unref(callbacks);
+
+ lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
+ enable_publish(pauline, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,1));
+ enable_publish(marie, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1));
+
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(marie->lc, f);
+
+ linphone_core_set_presence_model(pauline->lc, pauline_presence);
+ linphone_presence_model_unref(pauline_presence);
+ linphone_core_set_presence_model(marie->lc, marie_presence);
+ linphone_presence_model_unref(marie_presence);
+
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,2));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2));
+
+ BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,1));
+
+ linphone_friend_enable_subscribes(f2, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f2,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline->lc, f2);
+
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityTV,1));
+ linphone_friend_invalidate_subscription(f);
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_update_subscribes(f,FALSE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,3));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+
+ linphone_friend_enable_subscribes(f, FALSE);
+ linphone_friend_enable_subscribes(f2, FALSE);
+ wait_for_list(lcs,NULL, 0, 5000); // wait for unsubscritptions
+ linphone_friend_unref(f);
+ linphone_friend_unref(f2);
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(marie->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ wait_for_list(lcs,NULL, 0, 2000); // wait for unsubscritptions
+
+ linphone_core_manager_stop(marie);
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,2,int,"%i");
+ linphone_core_manager_destroy(marie);
+
+ linphone_core_manager_stop(pauline);
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,2,int,"%i");
+ linphone_core_manager_destroy(pauline);
+
+ bctbx_list_free(lcs);
+}
+
+static void extended_notify_only_both_side_subscribed2(void) {
+ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
+ LinphonePresenceModel *marie_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityTV, NULL);
+ LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline));
+ LinphoneFriend* f2 = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
+ LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get());
+ bctbx_list_t *lcs = NULL;
+ lcs = bctbx_list_append(lcs, marie->lc);
+ lcs = bctbx_list_append(lcs, pauline->lc);
+
+ linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed);
+ _linphone_core_add_callbacks(marie->lc, callbacks, TRUE);
+ _linphone_core_add_callbacks(pauline->lc, callbacks, TRUE);
+ linphone_core_cbs_unref(callbacks);
+
+ lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
+ enable_publish(pauline, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,1));
+ enable_publish(marie, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1));
+
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(marie->lc, f);
+
+ linphone_core_set_presence_model(pauline->lc, pauline_presence);
+ linphone_core_set_presence_model(marie->lc, marie_presence);
+ linphone_presence_model_unref(marie_presence);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,2));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2));
+
+ BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,1));
+
+ linphone_friend_enable_subscribes(f2, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f2,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline->lc, f2);
+
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityTV,1));
+
+ linphone_core_set_presence_model(pauline->lc, pauline_presence);
+ linphone_presence_model_unref(pauline_presence);
+
+ enable_publish(pauline, FALSE);
+ enable_publish(pauline, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,3));
+
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,3));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+
+ linphone_friend_enable_subscribes(f, FALSE);
+ linphone_friend_enable_subscribes(f2, FALSE);
+ wait_for_list(lcs,NULL, 0, 5000); // wait for unsubscritptions
+ linphone_friend_unref(f);
+ linphone_friend_unref(f2);
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(marie->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ wait_for_list(lcs,NULL, 0, 2000); // wait for unsubscritptions
+
+ linphone_core_manager_stop(marie);
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,2,int,"%i");
+ linphone_core_manager_destroy(marie);
+
+ linphone_core_manager_stop(pauline);
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,2,int,"%i");
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,3,int,"%i");
+ linphone_core_manager_destroy(pauline);
+
+ bctbx_list_free(lcs);
+}
+
+static void extended_notify_sub_unsub_sub(void) {
+ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
+ LinphonePresenceModel *marie_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityTV, NULL);
+ LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline));
+ LinphoneFriend* f2 = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
+ LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get());
+ bctbx_list_t *lcs = NULL;
+ lcs = bctbx_list_append(lcs, marie->lc);
+ lcs = bctbx_list_append(lcs, pauline->lc);
+
+ linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed);
+ _linphone_core_add_callbacks(marie->lc, callbacks, TRUE);
+ _linphone_core_add_callbacks(pauline->lc, callbacks, TRUE);
+ linphone_core_cbs_unref(callbacks);
+
+ lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
+
+ linphone_core_set_presence_model(pauline->lc, pauline_presence);
+ linphone_core_set_presence_model(marie->lc, marie_presence);
+ linphone_presence_model_unref(pauline_presence);
+ linphone_presence_model_unref(marie_presence);
+
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(marie->lc, f);
+
+ linphone_friend_enable_subscribes(f2, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f2,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline->lc, f2);
+
+ enable_publish(pauline, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,1));
+ enable_publish(marie, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1));
+
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,1));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityTV,1));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ wait_for_until(pauline->lc, NULL, NULL, 0,2000); /*wait for unsubscribe*/
+ linphone_friend_invalidate_subscription(f);
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_update_subscribes(f,FALSE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,2));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1));
+ BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(f), int, "%d");
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), TRUE);
+ linphone_friend_invalidate_subscription(f);
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_update_subscribes(f,FALSE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NotifyPresenceReceived,2));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityTV,2));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,3));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,2));
+
+ linphone_friend_enable_subscribes(f, FALSE);
+ linphone_friend_enable_subscribes(f2, FALSE);
+ wait_for_list(lcs,NULL, 0, 5000); // wait for unsubscritptions
+ linphone_friend_unref(f);
+ linphone_friend_unref(f2);
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(marie->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ wait_for_list(lcs,NULL, 0, 2000); // wait for unsubscritptions
+
+ linphone_core_manager_stop(marie);
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,1,int,"%i");
+ linphone_core_manager_destroy(marie);
+
+ linphone_core_manager_stop(pauline);
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,1,int,"%i");
+ linphone_core_manager_destroy(pauline);
+
+ bctbx_list_free(lcs);
+}
+
+static void extended_notify_sub_unsub_sub2(void) {
+ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ LinphoneCoreManager* pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+ LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityAppointment, NULL);
+ LinphonePresenceModel *pauline_presence2 = linphone_presence_model_new_with_activity(LinphonePresenceActivityOnThePhone, NULL);
+ LinphonePresenceModel *marie_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityTV, NULL);
+ LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline));
+ LinphoneFriend* f2 = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
+ LinphoneFriend* f3 = linphone_core_create_friend_with_address(pauline2->lc, get_identity(marie));
+ LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get());
+ int old_marie_nb_phone = 0;
+ int old_marie_nb_appointment = 0;
+ bctbx_list_t *lcs = NULL;
+ lcs = bctbx_list_append(lcs, marie->lc);
+ lcs = bctbx_list_append(lcs, pauline->lc);
+ lcs = bctbx_list_append(lcs, pauline2->lc);
+
+ linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed);
+ _linphone_core_add_callbacks(marie->lc, callbacks, TRUE);
+ _linphone_core_add_callbacks(pauline->lc, callbacks, TRUE);
+ _linphone_core_add_callbacks(pauline2->lc, callbacks, TRUE);
+ linphone_core_cbs_unref(callbacks);
+
+ lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
+ linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(pauline2->lc, "full-presence-support", NULL);
+ linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
+
+ linphone_core_set_presence_model(pauline->lc, pauline_presence);
+ linphone_core_set_presence_model(pauline2->lc, pauline_presence2);
+ linphone_core_set_presence_model(marie->lc, marie_presence);
+ linphone_presence_model_unref(pauline_presence);
+ linphone_presence_model_unref(pauline_presence2);
+ linphone_presence_model_unref(marie_presence);
+
+ linphone_friend_enable_subscribes(f2, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f2,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline->lc, f2);
+
+ linphone_friend_enable_subscribes(f3, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f3,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(pauline2->lc, f3);
+
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_set_inc_subscribe_policy(f,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
+ linphone_core_add_friend(marie->lc, f);
+
+ enable_publish(pauline, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,1));
+ enable_publish(pauline2, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline2->lc,&pauline2->stat.number_of_LinphonePublishOk,1));
+ enable_publish(marie, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1));
+
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityTV,1));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline2->lc,&pauline2->stat.number_of_LinphonePresenceActivityTV,1));
+
+ wait_for_until(marie->lc,pauline->lc,NULL,0,2000);
+ old_marie_nb_appointment = marie->stat.number_of_LinphonePresenceActivityAppointment;
+ old_marie_nb_phone = marie->stat.number_of_LinphonePresenceActivityOnThePhone;
+ BC_ASSERT_GREATER(old_marie_nb_phone, 0 , int, "%d");
+ BC_ASSERT_GREATER(old_marie_nb_appointment, 0 , int, "%d");
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ enable_publish(pauline, FALSE);
+ wait_for_until(pauline->lc, NULL, NULL, 0,2000); //wait for unsubscribe
+ linphone_friend_invalidate_subscription(f);
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_update_subscribes(f,FALSE);
+ wait_for_until(marie->lc,pauline->lc,NULL,0,2000);
+ BC_ASSERT_EQUAL(old_marie_nb_appointment, marie->stat.number_of_LinphonePresenceActivityAppointment, int, "%d");
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone - old_marie_nb_phone, 1, int, "%d");
+ old_marie_nb_appointment = marie->stat.number_of_LinphonePresenceActivityAppointment;
+ old_marie_nb_phone = marie->stat.number_of_LinphonePresenceActivityOnThePhone;
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), TRUE);
+ enable_publish(pauline, TRUE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,2));
+
+ linphone_friend_invalidate_subscription(f);
+ linphone_friend_enable_subscribes(f, TRUE);
+ linphone_friend_update_subscribes(f,FALSE);
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityTV,2));
+ BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,7));
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone - old_marie_nb_phone, marie->stat.number_of_LinphonePresenceActivityAppointment - old_marie_nb_appointment, int, "%d");
+
+ linphone_friend_enable_subscribes(f, FALSE);
+ linphone_friend_enable_subscribes(f2, FALSE);
+ linphone_friend_enable_subscribes(f3, FALSE);
+ wait_for_list(lcs,NULL, 0, 5000); // wait for unsubscritptions
+ linphone_friend_unref(f);
+ linphone_friend_unref(f2);
+ linphone_friend_unref(f3);
+
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(marie->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline->lc), FALSE);
+ linphone_friend_list_enable_subscriptions(linphone_core_get_default_friend_list(pauline2->lc), FALSE);
+ wait_for_list(lcs,NULL, 0, 2000); // wait for unsubscritptions
+
+ linphone_core_manager_stop(marie);
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,1,int,"%i");
+ linphone_core_manager_destroy(marie);
+
+ linphone_core_manager_stop(pauline);
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,2,int,"%i");
+ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,2,int,"%i");
+ linphone_core_manager_destroy(pauline);
+
+ linphone_core_manager_stop(pauline2);
+ BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphonePublishCleared,1,int,"%i");
+ BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphonePublishOk,1,int,"%i");
+ linphone_core_manager_destroy(pauline2);
+
+ bctbx_list_free(lcs);
}
test_t presence_server_tests[] = {
@@ -1185,6 +1586,10 @@ test_t presence_server_tests[] = {
TEST_NO_TAG("Subscriber no longer reachable using server",subscriber_no_longer_reachable),
TEST_NO_TAG("Subscribe with late publish", subscribe_with_late_publish),
TEST_NO_TAG("Multiple publish aggregation", multiple_publish_aggregation),
+ TEST_NO_TAG("Extended notify only when both side subscribed to each other", extended_notify_only_both_side_subscribed),
+ TEST_NO_TAG("Extended notify only when both side subscribed to each other 2", extended_notify_only_both_side_subscribed2),
+ TEST_NO_TAG("Extended notify only when subscribe then unsubscribe then re-subscribe", extended_notify_sub_unsub_sub),
+ TEST_NO_TAG("Extended notify only when subscribe then unsubscribe then re-subscribe 2", extended_notify_sub_unsub_sub2),
};
test_suite_t presence_server_test_suite = {"Presence using server", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c
index b137df936..27c4063f0 100644
--- a/tester/proxy_config_tester.c
+++ b/tester/proxy_config_tester.c
@@ -127,6 +127,11 @@ static void phone_normalization_with_proxy(void) {
BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "+990123456789");
BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "+991234567890");
+ // Phone normalization for mexican dial plans
+ linphone_proxy_config_set_dial_prefix(proxy, "52");
+ BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+5217227718184"), "+5217227718184"); /*this is a mobile phone number */
+ BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+528127718184"), "+528127718184"); /*this is a landline phone number from Monterrey*/
+
linphone_proxy_config_unref(proxy);
}
diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c
index 89274ff62..d4031715a 100644
--- a/tester/vcard_tester.c
+++ b/tester/vcard_tester.c
@@ -147,6 +147,7 @@ static void linphone_vcard_phone_numbers_and_sip_addresses(void) {
LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE);
LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nIMPP;TYPE=home:sip:sylvain@sip.linphone.org\r\nTEL;TYPE=work:0952636505\r\nEND:VCARD\r\n");
LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc);
+ linphone_vcard_unref(lvc);
const bctbx_list_t *sip_addresses = linphone_friend_get_addresses(lf);
bctbx_list_t *phone_numbers = linphone_friend_get_phone_numbers(lf);
LinphoneAddress *addr = NULL;
@@ -158,6 +159,7 @@ static void linphone_vcard_phone_numbers_and_sip_addresses(void) {
lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nTEL;TYPE=work:0952636505\r\nTEL:0476010203\r\nEND:VCARD\r\n");
lf = linphone_friend_new_from_vcard(lvc);
+ linphone_vcard_unref(lvc);
lf->lc = manager->lc;
sip_addresses = linphone_friend_get_addresses(lf);
phone_numbers = linphone_friend_get_phone_numbers(lf);
@@ -301,6 +303,7 @@ static void friends_sqlite_storage(void) {
linphone_vcard_set_etag(lvc, "\"123-456789\"");
linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf");
lf = linphone_friend_new_from_vcard(lvc);
+ linphone_vcard_unref(lvc);
linphone_friend_set_address(lf, addr);
linphone_friend_set_name(lf, "Sylvain");
@@ -363,6 +366,7 @@ static void friends_sqlite_storage(void) {
BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(friends), 0, unsigned int, "%u");
friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(friends_from_db), 0, unsigned int, "%u");
+ friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);
linphone_core_remove_friend_list(lc, lfl);
wait_for_until(lc, NULL, &stats->removed_list_count, 1, 1000);
@@ -635,6 +639,7 @@ static void carddav_sync_3(void) {
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
LinphoneCardDavContext *c = NULL;
+ linphone_vcard_unref(lvc);
linphone_friend_list_set_uri(lfl, CARDDAV_SERVER);
linphone_core_add_friend_list(manager->lc, lfl);
linphone_friend_list_unref(lfl);
@@ -674,6 +679,7 @@ static void carddav_sync_4(void) {
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
LinphoneCardDavContext *c = NULL;
+ linphone_vcard_unref(lvc);
linphone_friend_list_set_uri(lfl, CARDDAV_SERVER);
linphone_core_add_friend_list(manager->lc, lfl);
linphone_friend_list_unref(lfl);
@@ -740,6 +746,7 @@ static void carddav_integration(void) {
char *address = NULL;
const LinphoneAddress *addr;
+ linphone_vcard_unref(lvc);
linphone_friend_list_set_uri(lfl, CARDDAV_SERVER);
cbs = linphone_friend_list_get_callbacks(lfl);
linphone_friend_list_cbs_set_user_data(cbs, stats);
@@ -766,12 +773,14 @@ static void carddav_integration(void) {
lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n");
lf = linphone_friend_new_from_vcard(lvc);
+ linphone_vcard_unref(lvc);
BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d");
linphone_friend_unref(lf);
lvc2 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n");
linphone_vcard_set_url(lvc2, "/card.php/addressbooks/tester/default/me.vcf");
lf2 = linphone_friend_new_from_vcard(lvc2);
+ linphone_vcard_unref(lvc2);
linphone_friend_set_ref_key(lf2, refkey);
BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf2), LinphoneFriendListOK, int, "%d");
@@ -853,6 +862,7 @@ static void carddav_clean(void) { // This is to ensure the content of the test
lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n");
linphone_vcard_set_url(lvc, "http://dav.linphone.org/card.php/addressbooks/tester/default/me.vcf");
lf = linphone_friend_new_from_vcard(lvc);
+ linphone_vcard_unref(lvc);
linphone_friend_list_add_friend(lfl, lf);
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, CARDDAV_SYNC_TIMEOUT);
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
@@ -904,6 +914,8 @@ static void carddav_server_to_client_and_client_to_sever_sync(void) {
LinphoneFriend *lf2 = linphone_friend_new_from_vcard(lvc2);
bctbx_list_t *friends = NULL, *friends_iterator = NULL;
+ linphone_vcard_unref(lvc1);
+ linphone_vcard_unref(lvc2);
linphone_friend_list_cbs_set_user_data(cbs, stats);
linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created);
linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted);
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index a4403e974..f26b5491f 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -54,8 +54,14 @@ add_executable(xml2lpc_test ${USE_BUNDLE} ${LP_XML2LPC_TEST_SOURCE_FILES})
target_link_libraries(xml2lpc_test ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES})
set_target_properties(xml2lpc_test PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
+set(LP_TEST_ECC_SOURCE_FILES test_ecc.c)
+bc_apply_compile_flags(LP_TEST_ECC_SOURCE_FILES STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
+add_executable(lp-test-ecc ${USE_BUNDLE} ${LP_TEST_ECC_SOURCE_FILES})
+target_link_libraries(lp-test-ecc ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES})
+set_target_properties(lp-test-ecc PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
+
if (NOT IOS)
- install(TARGETS lp-auto-answer lp-sendmsg lpc2xml_test xml2lpc_test
+ install(TARGETS lp-auto-answer lp-sendmsg lpc2xml_test xml2lpc_test lp-test-ecc
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
diff --git a/tools/abstractapi.py b/tools/abstractapi.py
index 27ff941f3..00ab7d076 100644
--- a/tools/abstractapi.py
+++ b/tools/abstractapi.py
@@ -799,6 +799,8 @@ class CParser(object):
absType.isref = cType.completeType.endswith('*')
elif cType.ctype == self.cListType:
absType = ListType(cType.containedType)
+ elif cType.ctype.endswith('Mask'):
+ absType = BaseType('integer', isUnsigned=True)
else:
raise Error('Unknown C type \'{0}\''.format(cType.ctype))
diff --git a/wrappers/cpp/class_header.mustache b/wrappers/cpp/class_header.mustache
index 6e4e94876..b81329836 100644
--- a/wrappers/cpp/class_header.mustache
+++ b/wrappers/cpp/class_header.mustache
@@ -37,6 +37,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
{{/isfactory}}{{/_class}}
+{{#_class}}
+{{#isNotListener}}
+struct {{{privCClassName}}};
+{{/isNotListener}}
+{{/_class}}
+
+
namespace linphone {
{{#priorDeclarations}}
@@ -68,6 +75,7 @@ namespace linphone {
LINPHONECXX_PUBLIC ~{{{className}}}();
LINPHONECXX_PUBLIC const void *c_struct() const {return mPrivPtr;}
{{/isnotrefcountable}}
+ LINPHONECXX_PUBLIC {{{privCClassName}}} *cPtr() {return ({{{privCClassName}}} *)mPrivPtr;}
{{/isNotListener}}
{{#ismonolistenable}}
diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py
index c7b42f591..45773addd 100755
--- a/wrappers/cpp/genwrapper.py
+++ b/wrappers/cpp/genwrapper.py
@@ -85,6 +85,7 @@ class CppTranslator(object):
'isVcard' : (_class.name.to_c() == 'LinphoneVcard'),
'className' : CppTranslator.translate_class_name(_class.name),
'cClassName' : '::' + _class.name.to_c(),
+ 'privCClassName' : '_' + _class.name.to_c(),
'parentClassName' : 'Object' if _class.refcountable else None,
'methods' : [],
'staticMethods' : [],
diff --git a/wrappers/cpp/tools.cc b/wrappers/cpp/tools.cc
index 9f7cdc9a7..1ebe600cb 100644
--- a/wrappers/cpp/tools.cc
+++ b/wrappers/cpp/tools.cc
@@ -73,8 +73,8 @@ const char *StringUtilities::cppStringToC(const std::string &cppstr) {
std::list StringUtilities::cStringArrayToCppList(const char **cArray) {
list cppList;
- int i;
- for(i=0; cArray[i]!=NULL; i++) {
+ if (cArray == NULL) return cppList;
+ for(int i=0; cArray[i]!=NULL; i++) {
cppList.push_back(cArray[i]);
}
return cppList;