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;