diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt index 206ed985a..d4dc9d259 100644 --- a/console/CMakeLists.txt +++ b/console/CMakeLists.txt @@ -38,6 +38,8 @@ endif() add_executable(linphonec ${LINPHONEC_SOURCE_FILES}) target_link_libraries(linphonec ${LINPHONE_LIBS_FOR_TOOLS} ${BCTOOLBOX_CORE_LIBRARIES} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES}) +set_target_properties(linphonec PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") + if(INTL_FOUND) target_link_libraries(linphonec ${INTL_LIBRARIES}) endif() @@ -52,6 +54,7 @@ endif() add_executable(linphonecsh ${LINPHONECSH_SOURCE_FILES}) target_link_libraries(linphonecsh ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES}) +set_target_properties(linphonecsh PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") set(INSTALL_TARGETS linphonec linphonecsh) if(WIN32) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index ead252c1f..e560833b0 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -125,6 +125,14 @@ void linphone_account_creator_cbs_set_recover_phone_account(LinphoneAccountCreat cbs->recover_phone_account = cb; } +LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_is_phone_number_used(const LinphoneAccountCreatorCbs *cbs) { + return cbs->is_phone_number_used; +} + +void linphone_account_creator_cbs_set_is_phone_number_used(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb) { + cbs->is_phone_number_used = cb; +} + static void _linphone_account_creator_destroy(LinphoneAccountCreator *creator) { linphone_xml_rpc_session_release(creator->xmlrpc_session); /*this will drop all pending requests if any*/ @@ -138,6 +146,7 @@ static void _linphone_account_creator_destroy(LinphoneAccountCreator *creator) { if (creator->display_name) ms_free(creator->display_name); if (creator->phone_country_code) ms_free(creator->phone_country_code); if (creator->activation_code) ms_free(creator->activation_code); + if (creator->language) ms_free(creator->language); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneAccountCreator); @@ -290,6 +299,7 @@ const char * linphone_account_creator_get_username(const LinphoneAccountCreator LinphoneAccountCreatorStatus linphone_account_creator_set_phone_number(LinphoneAccountCreator *creator, const char *phone_number, const char *country_code) { char *normalized_phone_number; + LinphoneAccountCreatorStatus return_status; if (!phone_number || !country_code) { if (!phone_number && !country_code) { creator->phone_number = NULL; @@ -313,19 +323,24 @@ LinphoneAccountCreatorStatus linphone_account_creator_set_phone_number(LinphoneA const LinphoneDialPlan* plan = linphone_dial_plan_by_ccc(creator->phone_country_code); int size = (int)strlen(phone_number); if (linphone_dial_plan_is_generic(plan)) { - return LinphoneAccountCreatorCountryCodeInvalid; + return_status = LinphoneAccountCreatorCountryCodeInvalid; + goto end; } if (size < plan->nnl - 1) { - return LinphoneAccountCreatorPhoneNumberTooShort; + return_status = LinphoneAccountCreatorPhoneNumberTooShort; + goto end; } else if (size > plan->nnl + 1) { - return LinphoneAccountCreatorPhoneNumberTooLong; + return_status = LinphoneAccountCreatorPhoneNumberTooLong; + goto end; } } } set_string(&creator->phone_number, normalized_phone_number, TRUE); - ms_free(normalized_phone_number); + return_status = LinphoneAccountCreatorOK; - return LinphoneAccountCreatorOK; +end: + ms_free(normalized_phone_number); + return return_status; } const char * linphone_account_creator_get_phone_number(const LinphoneAccountCreator *creator) { @@ -337,7 +352,7 @@ LinphoneAccountCreatorStatus linphone_account_creator_set_password(LinphoneAccou int max_length = lp_config_get_int(creator->core->config, "assistant", "password_max_length", -1); if (!password) { creator->password = NULL; - return LinphoneAccountCreatorOK; + return LinphoneAccountCreatorPasswordTooShort; } if (min_length > 0 && strlen(password) < (size_t)min_length) { return LinphoneAccountCreatorPasswordTooShort; @@ -366,6 +381,11 @@ LinphoneAccountCreatorStatus linphone_account_creator_set_activation_code(Linpho return LinphoneAccountCreatorOK; } +LinphoneAccountCreatorStatus linphone_account_creator_set_language(LinphoneAccountCreator *creator, const char *lang) { + set_string(&creator->language, lang, FALSE); + return LinphoneAccountCreatorOK; +} + LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport){ if (!linphone_core_sip_transport_supported(creator->core, transport)) { return LinphoneAccountCreatorTransportNotSupported; @@ -520,6 +540,7 @@ LinphoneAccountCreatorStatus linphone_account_creator_is_account_used(LinphoneAc request = linphone_xml_rpc_request_new_with_args("get_phone_number_for_account", LinphoneXmlRpcArgString, LinphoneXmlRpcArgString, creator->username ? creator->username : creator->phone_number, + LinphoneXmlRpcArgString, creator->domain, LinphoneXmlRpcArgNone); linphone_xml_rpc_request_set_user_data(request, creator); @@ -538,7 +559,11 @@ static void _create_account_cb(LinphoneXmlRpcRequest *request) { LinphoneAccountCreatorStatus status = LinphoneAccountCreatorReqFailed; const char* resp = linphone_xml_rpc_request_get_string_response(request); if (linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) { - status = (strcmp(resp, "OK") == 0) ? LinphoneAccountCreatorAccountCreated : LinphoneAccountCreatorAccountNotCreated; + status = (strcmp(resp, "OK") == 0) ? LinphoneAccountCreatorAccountCreated + : (strcmp(resp, "ERROR_CANNOT_SEND_SMS") == 0) ? LinphoneAccountCreatorErrorServer + : (strcmp(resp, "ERROR_ACCOUNT_ALREADY_IN_USE") == 0) ? LinphoneAccountCreatorAccountExist + : (strcmp(resp, "ERROR_ALIAS_ALREADY_IN_USE") == 0) ? LinphoneAccountCreatorAccountExistWithAlias + :LinphoneAccountCreatorAccountNotCreated; } creator->callbacks->create_account(creator, status, resp); } @@ -554,6 +579,8 @@ static LinphoneXmlRpcRequest * _create_account_with_phone(LinphoneAccountCreator LinphoneXmlRpcArgString, creator->username ? creator->username : creator->phone_number, LinphoneXmlRpcArgString, creator->password ? ha1_for_passwd(creator->username ? creator->username : creator->phone_number, creator->password, creator->domain) : "", LinphoneXmlRpcArgString, linphone_core_get_user_agent(creator->core), + LinphoneXmlRpcArgString, creator->domain, + LinphoneXmlRpcArgString, creator->language, LinphoneXmlRpcArgNone); return request; } @@ -568,6 +595,7 @@ static LinphoneXmlRpcRequest * _create_account_with_email(LinphoneAccountCreator LinphoneXmlRpcArgString, creator->email, LinphoneXmlRpcArgString, ha1_for_passwd(creator->username ? creator->username : creator->phone_number, creator->password, creator->domain), LinphoneXmlRpcArgString, linphone_core_get_user_agent(creator->core), + LinphoneXmlRpcArgString, creator->domain, LinphoneXmlRpcArgNone); return request; } @@ -628,11 +656,13 @@ LinphoneAccountCreatorStatus linphone_account_creator_activate_account(LinphoneA LinphoneXmlRpcArgString, creator->phone_number, LinphoneXmlRpcArgString, creator->username ? creator->username : creator->phone_number, LinphoneXmlRpcArgString, creator->activation_code, + LinphoneXmlRpcArgString, creator->domain, LinphoneXmlRpcArgNone); } else { request = linphone_xml_rpc_request_new_with_args("activate_email_account", LinphoneXmlRpcArgString, LinphoneXmlRpcArgString, creator->username, LinphoneXmlRpcArgString, creator->activation_code, + LinphoneXmlRpcArgString, creator->domain, LinphoneXmlRpcArgNone); } linphone_xml_rpc_request_set_user_data(request, creator); @@ -667,7 +697,8 @@ LinphoneAccountCreatorStatus linphone_account_creator_is_account_activated(Linph return LinphoneAccountCreatorReqFailed; } request = linphone_xml_rpc_request_new_with_args("is_account_activated", LinphoneXmlRpcArgString, - LinphoneXmlRpcArgString, creator->phone_number ? creator->phone_number : creator->username, + LinphoneXmlRpcArgString, creator->username ? creator->username : creator->phone_number, + LinphoneXmlRpcArgString, creator->domain, LinphoneXmlRpcArgNone); linphone_xml_rpc_request_set_user_data(request, creator); linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _is_account_activated_cb); @@ -678,6 +709,45 @@ LinphoneAccountCreatorStatus linphone_account_creator_is_account_activated(Linph } /****************** END OF CREATE ACCOUNT VALIDATED SECTION********************/ +/****************** START OF PHONE NUMBER VALIDATED SECTION *******************/ + +static void _is_phone_number_used_cb(LinphoneXmlRpcRequest *request) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)linphone_xml_rpc_request_get_user_data(request); + if (creator->callbacks->is_phone_number_used != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorReqFailed; + const char* resp = linphone_xml_rpc_request_get_string_response(request); + if (linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) { + status = (strcmp(resp, "OK_ACCOUNT") == 0) ? LinphoneAccountCreatorPhoneNumberUsedAccount + : (strcmp(resp, "OK_ALIAS") == 0) ? LinphoneAccountCreatorPhoneNumberUsedAlias + : LinphoneAccountCreatorPhoneNumberNotUsed; + } + creator->callbacks->is_phone_number_used(creator, status, resp); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_is_phone_number_used(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity = _get_identity(creator); + if (!identity) { + if (creator->callbacks->is_phone_number_used != NULL) { + creator->callbacks->is_phone_number_used(creator, LinphoneAccountCreatorReqFailed, "Missing required parameters"); + } + return LinphoneAccountCreatorReqFailed; + } + request = linphone_xml_rpc_request_new_with_args("is_phone_number_used", LinphoneXmlRpcArgString, + LinphoneXmlRpcArgString, creator->phone_number, + LinphoneXmlRpcArgString, creator->domain, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_request_set_user_data(request, creator); + linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _is_phone_number_used_cb); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOK; +} + +/****************** END OF PHONE NUMBER VALIDATED SECTION *********************/ + /****************** START OF LINK PHONE NUMBER WITH ACCOUNT SECTION ***********/ static void _link_phone_number_with_account_cb(LinphoneXmlRpcRequest *request) { LinphoneAccountCreator *creator = (LinphoneAccountCreator *)linphone_xml_rpc_request_get_user_data(request); @@ -702,6 +772,8 @@ LinphoneAccountCreatorStatus linphone_account_creator_link_phone_number_with_acc request = linphone_xml_rpc_request_new_with_args("link_phone_number_with_account", LinphoneXmlRpcArgString, LinphoneXmlRpcArgString, creator->phone_number, LinphoneXmlRpcArgString, creator->username, + LinphoneXmlRpcArgString, creator->domain, + LinphoneXmlRpcArgString, creator->language, LinphoneXmlRpcArgNone); linphone_xml_rpc_request_set_user_data(request, creator); linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _link_phone_number_with_account_cb); @@ -767,6 +839,7 @@ LinphoneAccountCreatorStatus linphone_account_creator_activate_phone_number_link LinphoneXmlRpcArgString, creator->username, LinphoneXmlRpcArgString, creator->activation_code, LinphoneXmlRpcArgString, creator->ha1 ? creator->ha1 : ha1_for_passwd(creator->username, creator->domain, creator->password), + LinphoneXmlRpcArgString, creator->domain, LinphoneXmlRpcArgNone); linphone_xml_rpc_request_set_user_data(request, creator); linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _activate_phone_number_link_cb); @@ -784,7 +857,9 @@ static void _recover_phone_account_cb(LinphoneXmlRpcRequest *request) { const char* resp = linphone_xml_rpc_request_get_string_response(request); if (linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) { if (strstr(resp, "ERROR_") == resp) { - status = LinphoneAccountCreatorReqFailed; + status = (strstr(resp, "ERROR_CANNOT_SEND_SMS") == resp) ? LinphoneAccountCreatorErrorServer + : (strstr(resp, "ERROR_ACCOUNT_DOESNT_EXIST") == resp) ? LinphoneAccountCreatorAccountNotExist + : LinphoneAccountCreatorReqFailed; } else { status = LinphoneAccountCreatorOK; set_string(&creator->username, resp, FALSE); @@ -804,6 +879,8 @@ LinphoneAccountCreatorStatus linphone_account_creator_recover_phone_account(Linp } request = linphone_xml_rpc_request_new_with_args("recover_phone_account", LinphoneXmlRpcArgString, LinphoneXmlRpcArgString, creator->phone_number, + LinphoneXmlRpcArgString, creator->domain, + LinphoneXmlRpcArgString, creator->language, LinphoneXmlRpcArgNone); linphone_xml_rpc_request_set_user_data(request, creator); linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _recover_phone_account_cb); diff --git a/coreapi/account_creator.h b/coreapi/account_creator.h index f8400f02d..c308ba3df 100644 --- a/coreapi/account_creator.h +++ b/coreapi/account_creator.h @@ -53,20 +53,29 @@ typedef enum _LinphoneAccountCreatorStatus { LinphoneAccountCreatorAccountNotLinked, LinphoneAccountCreatorEmailInvalid, + LinphoneAccountCreatorUsernameInvalid, LinphoneAccountCreatorUsernameTooShort, LinphoneAccountCreatorUsernameTooLong, LinphoneAccountCreatorUsernameInvalidSize, + LinphoneAccountCreatorPhoneNumberInvalid, LinphoneAccountCreatorPhoneNumberTooShort, LinphoneAccountCreatorPhoneNumberTooLong, + LinphoneAccountCreatorPhoneNumberUsedAccount, + LinphoneAccountCreatorPhoneNumberUsedAlias, + LinphoneAccountCreatorPhoneNumberNotUsed, + LinphoneAccountCreatorPasswordTooShort, LinphoneAccountCreatorPasswordTooLong, + LinphoneAccountCreatorDomainInvalid, LinphoneAccountCreatorRouteInvalid, LinphoneAccountCreatorDisplayNameInvalid, LinphoneAccountCreatorTransportNotSupported, LinphoneAccountCreatorCountryCodeInvalid, + + LinphoneAccountCreatorErrorServer, } LinphoneAccountCreatorStatus; /** @@ -189,6 +198,13 @@ LINPHONE_PUBLIC const char * linphone_account_creator_get_ha1(const LinphoneAcco **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_activation_code(LinphoneAccountCreator *creator, const char *activation_code); +/** + * Set the language to use in email or SMS if supported. + * @param[in] creator LinphoneAccountCreator object + * @param[in] activation_code The language code to use +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_language(LinphoneAccountCreator *creator, const char *lang); + /** * Set the transport. * @param[in] creator LinphoneAccountCreator object @@ -299,6 +315,13 @@ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_a **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_activated(LinphoneAccountCreator *creator); +/** + * Send an XML-RPC request to test the existence a phone number with a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorReqFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_phone_number_used(LinphoneAccountCreator *creator); + /** * Send an XML-RPC request to link a phone number with a Linphone account. * @param[in] creator LinphoneAccountCreator object @@ -454,6 +477,20 @@ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_g **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_is_account_activated(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); +/** + * Get the is phone number used callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @return The current is phone number used callback +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_is_phone_number_used(const LinphoneAccountCreatorCbs *cbs); + +/** + * Set the is phone number used callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cb is phone number to be used. +**/ +LINPHONE_PUBLIC void linphone_account_creator_cbs_set_is_phone_number_used(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); + LINPHONE_PUBLIC void linphone_account_creator_cbs_set_recover_phone_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_recover_phone_account(const LinphoneAccountCreatorCbs *cbs); diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 4eb25b106..8ccde1378 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -1198,11 +1198,10 @@ SalResolverContext * sal_resolve(Sal *sal, const char *service, const char *tran return (SalResolverContext *)belle_sip_stack_resolve(sal->stack, service, transport, name, port, family, (belle_sip_resolver_callback_t)cb, data); } -/* -void sal_resolve_cancel(Sal *sal, SalResolverContext* ctx){ - belle_sip_stack_resolve_cancel(sal->stack,ctx); +void sal_resolve_cancel(SalResolverContext* ctx){ + belle_sip_resolver_context_cancel((belle_sip_resolver_context_t*)ctx); } -*/ + void sal_enable_unconditional_answer(Sal *sal,int value) { belle_sip_provider_enable_unconditional_answer(sal->prov,value); diff --git a/coreapi/event.c b/coreapi/event.c index c50ca460d..9eae159b8 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -135,6 +135,7 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s linphone_event_release(lev); break; case LinphonePublishOk: + if (lev->oneshot) linphone_event_release(lev); break; case LinphonePublishError: linphone_event_release(lev); @@ -275,6 +276,12 @@ LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddr return lev; } +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; + return lev; +} + static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneContent *body, bool_t notify_err){ SalBodyHandler *body_handler; int err; diff --git a/coreapi/event.h b/coreapi/event.h index 247df2a9d..47db9cc79 100644 --- a/coreapi/event.h +++ b/coreapi/event.h @@ -204,6 +204,19 @@ LINPHONE_PUBLIC LinphoneEvent *linphone_core_publish(LinphoneCore *lc, const Lin **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires); + +/** + * Create a publish context for a one-shot publish. + * After being created, the publish must be sent using linphone_event_send_publish(). + * The LinphoneEvent is automatically terminated when the publish transaction is finished, either with success or failure. + * The application must not call linphone_event_terminate() for such one-shot publish. + * @param lc the #LinphoneCore + * @param resource the resource uri for the event + * @param event the event name + * @return the LinphoneEvent holding the context of the publish. +**/ +LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_one_shot_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event); + /** * Send a publish created by linphone_core_create_publish(). * @param lev the #LinphoneEvent diff --git a/coreapi/ldap/ldapprovider.c b/coreapi/ldap/ldapprovider.c index 34460e1f4..4cd031a88 100644 --- a/coreapi/ldap/ldapprovider.c +++ b/coreapi/ldap/ldapprovider.c @@ -635,7 +635,7 @@ static unsigned int linphone_ldap_contact_provider_cancel_search(LinphoneContact bctbx_list_t* list_entry = bctbx_list_find_custom(ldap_cp->requests, linphone_ldap_request_entry_compare_strong, req); if( list_entry ) { ms_message("Delete search %p", req); - ldap_cp->requests = bctbx_list_remove_link(ldap_cp->requests, list_entry); + ldap_cp->requests = bctbx_list_erase_link(ldap_cp->requests, list_entry); ldap_cp->req_count--; ret = 0; // return OK if we found it in the monitored requests } else { diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 9252bda1b..3053a6094 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1086,7 +1086,7 @@ static void linphone_call_get_local_ip(LinphoneCall *call, const LinphoneAddress const char *ip = NULL; int af = call->af; const char *dest = NULL; - + if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseNatAddress && (ip=linphone_core_get_nat_address_resolved(call->core))!=NULL){ strncpy(call->media_localip,ip,LINPHONE_IPADDR_SIZE); @@ -1132,7 +1132,7 @@ static void linphone_call_get_local_ip(LinphoneCall *call, const LinphoneAddress } if (res != NULL) freeaddrinfo(res); } - + if (dest != NULL || call->media_localip[0] == '\0' || call->need_localip_refresh){ call->need_localip_refresh = FALSE; linphone_core_get_local_ip(call->core, af, dest, call->media_localip); @@ -1168,13 +1168,13 @@ void linphone_call_fill_media_multicast_addr(LinphoneCall *call) { void linphone_call_check_ice_session(LinphoneCall *call, IceRole role, bool_t is_reinvite){ if (call->ice_session) return; /*already created*/ - + if (!linphone_nat_policy_ice_enabled(linphone_core_get_nat_policy(call->core))){ return; } - + if (is_reinvite && lp_config_get_int(call->core->config, "net", "allow_late_ice", 0) == 0) return; - + call->ice_session = ice_session_new(); /*for backward compatibility purposes, shall be enabled by default in futur*/ ice_session_enable_message_integrity_check(call->ice_session,lp_config_get_int(call->core->config,"net","ice_session_enable_message_integrity_check",1)); @@ -1203,7 +1203,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr linphone_call_fill_media_multicast_addr(call); linphone_call_check_ice_session(call, IR_Controlling, FALSE); - + if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseStun) { call->ping_time=linphone_core_run_stun_tests(call->core,call); } @@ -1219,7 +1219,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr if (params->referer){ call->referer=linphone_call_ref(params->referer); } - + linphone_call_create_op(call); return call; } @@ -1251,7 +1251,7 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, S } else { call->params->avpf_rr_interval = linphone_core_get_avpf_rr_interval(call->core)*1000; } - + if ((sal_media_description_has_zrtp(md) == TRUE) && (linphone_core_media_encryption_supported(call->core, LinphoneMediaEncryptionZRTP) == TRUE)) { call->params->media_encryption = LinphoneMediaEncryptionZRTP; }else if ((sal_media_description_has_dtls(md) == TRUE) && (media_stream_dtls_supported() == TRUE)) { @@ -1261,7 +1261,7 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, S }else if (call->params->media_encryption != LinphoneMediaEncryptionZRTP){ call->params->media_encryption = LinphoneMediaEncryptionNone; } - + /*in case of nat64, even ipv4 addresses are reachable from v6. Should be enhanced to manage stream by stream connectivity (I.E v6 or v4)*/ /*if (!sal_media_description_has_ipv6(md)){ ms_message("The remote SDP doesn't seem to offer any IPv6 connectivity, so disabling IPv6 for this call."); @@ -1381,7 +1381,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro call->dest_proxy = linphone_core_lookup_known_proxy(call->core, to); linphone_call_incoming_select_ip_version(call, call->dest_proxy); - /*note that the choice of IP version for streams is later refined by + /*note that the choice of IP version for streams is later refined by * linphone_call_set_compatible_incoming_call_parameters() when examining the remote offer, if any. * If the remote offer contains IPv4 addresses, we should propose IPv4 as well*/ @@ -2171,7 +2171,7 @@ void linphone_call_enable_camera (LinphoneCall *call, bool_t enable){ video_stream_change_camera(call->videostream, linphone_call_get_video_device(call)); } break; - + default: break; } #endif @@ -4071,7 +4071,7 @@ float linphone_call_get_current_quality(LinphoneCall *call){ float linphone_call_get_average_quality(LinphoneCall *call){ float audio_rating=-1.f; float video_rating=-1.f; - + if (call->audiostream){ audio_rating = media_stream_get_average_quality_rating((MediaStream*)call->audiostream)/5.0f; } @@ -4351,6 +4351,13 @@ static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *v call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth=(vs_active) ? (float)(media_stream_get_rtcp_up_bw(vs)*1e-3) : 0.f; call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_download_bandwidth=(ts_active) ? (float)(media_stream_get_rtcp_down_bw(ts)*1e-3) : 0.f; call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_upload_bandwidth=(ts_active) ? (float)(media_stream_get_rtcp_up_bw(ts)*1e-3) : 0.f; + /* If not ipV6, it's not necessary IpV4, should be UNSPEC, TODO */ + call->stats[LINPHONE_CALL_STATS_AUDIO].rtp_remote_family=(as_active) + ? ((ortp_stream_is_ipv6((OrtpStream*)&(as->sessions.rtp_session->rtp.gs))) ? INET_6 : INET) : UNSPEC; + call->stats[LINPHONE_CALL_STATS_VIDEO].rtp_remote_family=(vs_active) + ? ((ortp_stream_is_ipv6((OrtpStream*)&(vs->sessions.rtp_session->rtp.gs))) ? INET_6 : INET) : UNSPEC; + call->stats[LINPHONE_CALL_STATS_TEXT].rtp_remote_family=(ts_active) + ? ((ortp_stream_is_ipv6((OrtpStream*)&(ts->sessions.rtp_session->rtp.gs))) ? INET_6 : INET) : UNSPEC; if (call->core->send_call_stats_periodical_updates){ call->stats[LINPHONE_CALL_STATS_AUDIO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; @@ -4598,11 +4605,11 @@ void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index){ OrtpEventType evt=ortp_event_get_type(ev); OrtpEventData *evd=ortp_event_get_data(ev); int stats_index = stream_index == call->main_audio_stream_index ? LINPHONE_CALL_STATS_AUDIO : (stream_index == call->main_video_stream_index ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT); - + /*and yes the MediaStream must be taken at each iteration, because it may have changed due to the handling of events * in this loop*/ ms = linphone_call_get_media_stream(call, stream_index); - + if (ms) linphone_call_stats_fill(&call->stats[stats_index],ms,ev); linphone_call_notify_stats_updated(call,stats_index); @@ -5073,12 +5080,12 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ /*Make sure that the proxy from which we received this call, or to which we routed this call is registered first*/ if (call->dest_proxy){ - /*in all other cases, ie no proxy config, or a proxy config for which no registration was requested, we can start the + /*in all other cases, ie no proxy config, or a proxy config for which no registration was requested, we can start the * call repair immediately.*/ - if (linphone_proxy_config_register_enabled(call->dest_proxy) + if (linphone_proxy_config_register_enabled(call->dest_proxy) && linphone_proxy_config_get_state(call->dest_proxy) != LinphoneRegistrationOk) return; } - + switch (call->state){ case LinphoneCallUpdating: diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index d81056acf..81c77edc0 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -74,28 +74,36 @@ typedef struct _LinphoneCore LinphoneCore; * Use with #LCSipTransports * @ingroup initializing */ -#define LC_SIP_TRANSPORT_RANDOM -1 +#define LC_SIP_TRANSPORT_RANDOM (-1) + +/** + * Don't create any server socket for this transport, ie don't bind on any port. + * Use with #LCSipTransports + * @ingroup initializing +**/ +#define LC_SIP_TRANSPORT_DONTBIND (-2) /** * Linphone core SIP transport ports. + * Special values LC_SIP_TRANSPORT_RANDOM, LC_SIP_TRANSPORT_RANDOM, #define LC_SIP_TRANSPORT_DONTBIND can be used. * Use with #linphone_core_set_sip_transports * @ingroup initializing */ typedef struct _LCSipTransports{ /** - * udp port to listening on, negative value if not set - * */ + * SIP/UDP port. + **/ int udp_port; /** - * tcp port to listening on, negative value if not set + * SIP/TCP port * */ int tcp_port; /** - * dtls port to listening on, negative value if not set + * SIP/DTLS port * */ int dtls_port; /** - * tls port to listening on, negative value if not set + * SIP/TLS port * */ int tls_port; } LCSipTransports; @@ -576,6 +584,22 @@ typedef enum _LinphoneUpnpState LinphoneUpnpState; #define LINPHONE_CALL_STATS_SENT_RTCP_UPDATE (1 << 1) /**< sent_rtcp field of LinphoneCallStats object has been updated */ #define LINPHONE_CALL_STATS_PERIODICAL_UPDATE (1 << 2) /**< Every seconds LinphoneCallStats object has been updated */ +/** + * Enum describing Ip family. + * @ingroup initializing +**/ +enum _linphoneAddressFamily { + INET, /* IpV4 */ + INET_6, /* IpV6 */ + UNSPEC, /* Unknown */ +}; + +/** + * Enum describing Ip family. + * @ingroup initializing +**/ +typedef enum _linphoneAddressFamily linphoneAddressFamily; + /** * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. * @@ -611,6 +635,7 @@ struct _LinphoneCallStats { float rtcp_upload_bandwidth; /**GetObjectClass(jhandler); loghandler_id = env->GetMethodID(handler_class, "log", "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V"); - + if (loghandler_id == NULL) { ms_fatal("log method not found"); } @@ -124,7 +124,7 @@ static void linphone_android_ortp_log_handler(const char *domain, OrtpLogLevel l case ORTP_FATAL: prio = ANDROID_LOG_FATAL; levname="fatal"; break; default: prio = ANDROID_LOG_DEFAULT; break; } - + if (handler_obj) { JNIEnv *env = ms_get_jni_env(); jstring jdomain = env->NewStringUTF(LogDomain); @@ -209,10 +209,10 @@ class LinphoneJavaBindings { public: LinphoneJavaBindings(JNIEnv *env) { listenerClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCoreListener")); - + authMethodClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$AuthMethod")); authMethodFromIntId = env->GetStaticMethodID(authMethodClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$AuthMethod;"); - + /*displayStatus(LinphoneCore lc,String message);*/ displayStatusId = env->GetMethodID(listenerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); @@ -288,7 +288,7 @@ public: chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State")); chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); - + authInfoClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAuthInfoImpl")); authInfoCtrId = env->GetMethodID(authInfoClass,"", "(J)V"); @@ -310,7 +310,7 @@ public: friendClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl")); friendCtrId = env->GetMethodID(friendClass,"", "(J)V"); - + friendListClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendListImpl")); friendListCtrId = env->GetMethodID(friendListClass,"", "(J)V"); friendListCreatedId = env->GetMethodID(listenerClass, "friendListCreated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V"); @@ -335,20 +335,20 @@ public: subscriptionDirClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionDir")); subscriptionDirFromIntId = env->GetStaticMethodID(subscriptionDirClass,"fromInt","(I)Lorg/linphone/core/SubscriptionDir;"); - + msFactoryClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/mediastream/Factory")); msFactoryCtrId = env->GetMethodID(msFactoryClass,"", "(J)V"); - + accountCreatorClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAccountCreatorImpl")); accountCreatorCtrId = env->GetMethodID(accountCreatorClass, "", "(J)V"); accountCreatorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAccountCreator$Status")); accountCreatorStatusFromIntId = env->GetStaticMethodID(accountCreatorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneAccountCreator$Status;"); } - + void setCore(jobject c) { core = c; } - + jobject getCore() { return core; } @@ -381,7 +381,7 @@ public: env->DeleteGlobalRef(accountCreatorClass); env->DeleteGlobalRef(accountCreatorStatusClass); } - + jobject core; jclass listenerClass; @@ -399,7 +399,7 @@ public: jmethodID authenticationRequestedId; jmethodID publishStateId; jmethodID notifyRecvId; - + jclass authMethodClass; jmethodID authMethodFromIntId; @@ -432,7 +432,7 @@ public: jclass ecCalibratorStatusClass; jmethodID ecCalibrationStatusId; jmethodID ecCalibratorStatusFromIntId; - + jclass authInfoClass; jmethodID authInfoCtrId; @@ -487,10 +487,10 @@ public: jmethodID logCollectionUploadStateId; jmethodID logCollectionUploadStateFromIntId; jmethodID logCollectionUploadProgressId; - + jclass msFactoryClass; jmethodID msFactoryCtrId; - + jclass accountCreatorClass; jmethodID accountCreatorCtrId; jclass accountCreatorStatusClass; @@ -612,7 +612,7 @@ jobject getChatRoom(JNIEnv *env, LinphoneChatRoom *room) { jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ jobject jobj=0; - + if (lfriend != NULL){ LinphoneCore *lc = linphone_friend_get_core(lfriend); LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); @@ -706,7 +706,7 @@ jobject getXmlRpcRequest(JNIEnv *env, LinphoneXmlRpcRequest *lrequest) { if (lrequest != NULL) { jclass xmlRpcSessionClass = (jclass)env->FindClass("org/linphone/core/LinphoneXmlRpcRequestImpl"); jmethodID xmlRpcSessionCtrId = env->GetMethodID(xmlRpcSessionClass, "", "(J)V"); - + void *up = linphone_xml_rpc_request_get_user_data(lrequest); if (up == NULL) { jobj = env->NewObject(xmlRpcSessionClass, xmlRpcSessionCtrId, (jlong)lrequest); @@ -751,7 +751,7 @@ public: LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener, LinphoneJavaBindings *ljb) { core = env->NewGlobalRef(lc); listener = env->NewGlobalRef(alistener); - + memset(vTable, 0, sizeof(LinphoneCoreVTable)); if (ljb->displayStatusId) { @@ -789,7 +789,7 @@ public: if (ljb->authInfoRequestedId) { vTable->auth_info_requested = authInfoRequested; } - + if (ljb->authenticationRequestedId) { vTable->authentication_requested = authenticationRequested; } @@ -848,7 +848,7 @@ public: if (ljb->logCollectionUploadStateId) { vTable->log_collection_upload_state_changed = logCollectionUploadStateChange; } - + if (ljb->friendListCreatedId) { vTable->friend_list_created = friendListCreated; } @@ -856,14 +856,14 @@ public: vTable->friend_list_removed = friendListRemoved; } } - + ~LinphoneCoreData() { JNIEnv *env = 0; jvm->AttachCurrentThread(&env,NULL); env->DeleteGlobalRef(core); env->DeleteGlobalRef(listener); } - + jobject core; jobject listener; @@ -876,7 +876,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -894,7 +894,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -926,7 +926,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -946,7 +946,7 @@ public: env->SetLongField(jcore, myFieldID, (jlong)lc); } } - + static void globalStateChange(LinphoneCore *lc, LinphoneGlobalState gstate,const char* message) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); @@ -954,15 +954,15 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - + jobject jcore = lcData->core; /*at this stage, the java object may not be aware of its C object, because linphone_core_new() hasn't returned yet.*/ setCoreIfNotDone(env,jcore, lc); - + jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener ,ljb->globalStateId @@ -982,7 +982,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1010,7 +1010,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1037,7 +1037,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1053,12 +1053,12 @@ public: JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); jobject jfriend = NULL; - + if (result != 0) { ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1077,7 +1077,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1097,7 +1097,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1115,7 +1115,7 @@ public: ms_error("cannot attach VM"); return; } - + jobject jmsg; jobject jroom; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); @@ -1128,7 +1128,7 @@ public: ,(jroom = getChatRoom(env, room)) ,(jmsg = getChatMessage(env, msg))); handle_possible_java_exception(env, lcData->listener); - + if (jmsg) { env->DeleteLocalRef(jmsg); } @@ -1143,7 +1143,7 @@ public: ms_error("cannot attach VM"); return; } - + jobject jroom; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); @@ -1153,7 +1153,7 @@ public: ,lcData->core ,(jroom = getChatRoom(env, room))); handle_possible_java_exception(env, lcData->listener); - + if (jroom) { env->DeleteLocalRef(jroom); } @@ -1195,7 +1195,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1220,7 +1220,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1239,7 +1239,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneInfoMessage *copy_info=linphone_info_message_copy(info); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); @@ -1261,7 +1261,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1289,7 +1289,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1311,7 +1311,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1333,7 +1333,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1350,7 +1350,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1379,7 +1379,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1412,7 +1412,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1443,7 +1443,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1461,7 +1461,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1483,7 +1483,7 @@ public: ms_error("cannot attach VM"); return; } - + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1500,7 +1500,7 @@ public: ms_error("cannot attach VM"); return; } - + jobject jfriendlist; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); @@ -1510,7 +1510,7 @@ public: ,lcData->core ,(jfriendlist = getFriendList(env, list))); handle_possible_java_exception(env, lcData->listener); - + if (jfriendlist) { env->DeleteLocalRef(jfriendlist); } @@ -1538,7 +1538,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* const char* factoryConfig = GetStringUTFChars(env, jfactoryConfig); LinphoneJavaBindings *ljb = new LinphoneJavaBindings(env); - + LinphoneCoreVTable *vTable = linphone_core_v_table_new(); LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener, ljb); linphone_core_v_table_set_user_data(vTable, ldata); @@ -1733,7 +1733,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigLi } proxies = proxies->next; } - + return jProxies; } @@ -2318,7 +2318,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN } friends = friends->next; } - + return jFriends; } @@ -2338,7 +2338,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendLists(J } friends = friends->next; } - + return jFriends; } @@ -3360,6 +3360,10 @@ extern "C" jstring Java_org_linphone_core_LinphoneCallStatsImpl_getDecoderName(J return jdecodername; } +extern "C" jint Java_org_linphone_core_LinphoneCallStatsImpl_getIpFamilyOfRemote(JNIEnv *env, jobject thiz, jlong stats_ptr) { + return (jint) ((LinphoneCallStats *)stats_ptr)->rtp_remote_family; +} + /*payloadType*/ extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env,jobject thiz,jlong ptr) { PayloadType* pt = (PayloadType*)ptr; @@ -3608,7 +3612,7 @@ static void contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); - + if (listener == NULL) { ms_error("contact_created() notification without listener"); return ; @@ -3635,7 +3639,7 @@ static void contact_updated(LinphoneFriendList *list, LinphoneFriend *lf_new, Li LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); - + if (listener == NULL) { ms_error("contact_updated() notification without listener"); return ; @@ -3664,7 +3668,7 @@ static void contact_removed(LinphoneFriendList *list, LinphoneFriend *lf) { LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); - + if (listener == NULL) { ms_error("contact_removed() notification without listener"); return ; @@ -3691,7 +3695,7 @@ static void sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSync LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); - + if (listener == NULL) { ms_error("sync_status_changed() notification without listener"); return ; @@ -3700,7 +3704,7 @@ static void sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSync jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendSyncStatusChanged","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriendList$State;Ljava/lang/String;)V"); jobject jlist = getFriendList(env, list); env->DeleteLocalRef(clazz); - + LinphoneCore *lc = linphone_friend_list_get_core((LinphoneFriendList *)list); LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); jstring msg = message ? env->NewStringUTF(message) : NULL; @@ -3831,7 +3835,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneFriendListImpl_getFriendL } friends = friends->next; } - + return jFriends; } @@ -4124,7 +4128,7 @@ extern "C" jobjectArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env, jobject th bctbx_list_t *list = history; size_t historySize = bctbx_list_size(history); jobjectArray jHistory = env->NewObjectArray(historySize, ljb->chatMessageClass, NULL); - + for (size_t i = 0; i < historySize; i++) { LinphoneChatMessage *msg = (LinphoneChatMessage *)history->data; jobject jmsg = getChatMessage(env, msg); @@ -4132,7 +4136,7 @@ extern "C" jobjectArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env, jobject th env->SetObjectArrayElement(jHistory, i, jmsg); env->DeleteLocalRef(jmsg); } - + history = history->next; } /*getChatMessage() acquired a ref that is "transfered" to the java object. We must drop @@ -4233,17 +4237,17 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferM linphone_content_set_type(content, tmp = GetStringUTFChars(env, jtype)); ReleaseStringUTFChars(env, jtype, tmp); - + linphone_content_set_subtype(content, tmp = GetStringUTFChars(env, jsubtype)); ReleaseStringUTFChars(env, jsubtype, tmp); - + linphone_content_set_name(content, tmp = GetStringUTFChars(env, jname)); ReleaseStringUTFChars(env, jname, tmp); - + linphone_content_set_size(content, data_size); - + message = linphone_chat_room_create_file_transfer_message((LinphoneChatRoom *)ptr, content); - + linphone_content_unref(content); return (jlong) message; @@ -4419,7 +4423,7 @@ static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageS } jobject listener = (jobject) msg->message_state_changed_user_data; - + if (listener == NULL) { ms_error("message_state_changed() notification without listener"); return ; @@ -5462,7 +5466,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_tunnelGetServers const bctbx_list_t *servers = linphone_tunnel_get_servers(tunnel); const bctbx_list_t *it; int i; - + tunnelConfigArray = env->NewObjectArray(bctbx_list_size(servers), tunnelConfigClass, NULL); for(it = servers, i=0; it != NULL; it = it->next, i++) { LinphoneTunnelConfig *conf = (LinphoneTunnelConfig *)it->data; @@ -5703,20 +5707,20 @@ static LinphoneContent *create_content_from_java_args(JNIEnv *env, LinphoneCore linphone_content_set_type(content, tmp = GetStringUTFChars(env, jtype)); ReleaseStringUTFChars(env, jtype, tmp); - + linphone_content_set_subtype(content, tmp = GetStringUTFChars(env, jsubtype)); ReleaseStringUTFChars(env, jsubtype, tmp); - + if (jname){ linphone_content_set_name(content, tmp = GetStringUTFChars(env, jname)); ReleaseStringUTFChars(env, jname, tmp); } - + if (jencoding){ linphone_content_set_encoding(content, tmp = GetStringUTFChars(env, jencoding)); ReleaseStringUTFChars(env, jencoding, tmp); } - + linphone_content_set_buffer(content, data, env->GetArrayLength(jdata)); env->ReleaseByteArrayElements(jdata,(jbyte*)data,JNI_ABORT); } @@ -5737,7 +5741,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIE jobject jev=NULL; const char *evname = GetStringUTFChars(env, jevname); - + ev=linphone_core_subscribe(lc,addr,evname,expires, content); if (content) linphone_content_unref(content); ReleaseStringUTFChars(env, jevname, evname); @@ -6011,16 +6015,16 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_setContent LinphoneInfoMessage *infomsg = (LinphoneInfoMessage*) infoptr; LinphoneContent * content = linphone_content_new(); const char *tmp; - + linphone_content_set_type(content, tmp = GetStringUTFChars(env, jtype)); ReleaseStringUTFChars(env, jtype, tmp); - + linphone_content_set_type(content, tmp = GetStringUTFChars(env, jsubtype)); ReleaseStringUTFChars(env, jsubtype, tmp); - + linphone_content_set_string_buffer(content, tmp = GetStringUTFChars(env, jdata)); ReleaseStringUTFChars(env, jdata, tmp); - + linphone_info_message_set_content(infomsg, content); linphone_content_unref(content); } @@ -6143,7 +6147,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN jtype, jsubtype, jdata, jencoding, NULL); LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; - + err=linphone_event_update_publish(ev, content); if (content) linphone_content_unref(content); @@ -6214,7 +6218,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_createSubscrib JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneEventImpl_sendSubscribe(JNIEnv *env, jobject thiz, jlong eventptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding) { LinphoneContent *content = create_content_from_java_args(env, linphone_event_get_core((LinphoneEvent*)eventptr), jtype, jsubtype, jdata, jencoding, NULL); - + linphone_event_send_subscribe((LinphoneEvent*) eventptr, content); if (content) linphone_content_unref(content); } @@ -7383,7 +7387,7 @@ extern "C" jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_videoMultica JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setDnsServers(JNIEnv *env, jobject thiz, jlong lc, jobjectArray servers){ bctbx_list_t *l = NULL; - + if (servers != NULL){ int count = env->GetArrayLength(servers); @@ -7723,7 +7727,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneConferenceImpl_getPartici jmethodID addr_constructor = env->GetMethodID(addr_class, "", "(J)V"); jobjectArray jaddr_list; int i; - + participants = linphone_conference_get_participants((LinphoneConference *)pconference); jaddr_list = env->NewObjectArray(bctbx_list_size(participants), addr_class, NULL); for(it=participants, i=0; it; it=bctbx_list_next(it), i++) { @@ -7861,18 +7865,18 @@ static void xml_request_response(LinphoneXmlRpcRequest *request) { ms_error("cannot attach VM\n"); return; } - + LinphoneXmlRpcRequestCbs *cbs = linphone_xml_rpc_request_get_callbacks(request); jobject listener = (jobject) linphone_xml_rpc_request_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("xml_request_response() notification without listener"); return ; } - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onXmlRpcRequestResponse","(Lorg/linphone/core/LinphoneXmlRpcRequest;)V"); env->DeleteLocalRef(clazz); - + env->CallVoidMethod(listener, method, getXmlRpcRequest(env, request)); } @@ -7969,14 +7973,14 @@ static void account_creator_is_account_used(LinphoneAccountCreator *creator, Lin ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorIsAccountUsed","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -7988,21 +7992,21 @@ static void account_creator_create_account(LinphoneAccountCreator *creator, Linp ms_error("cannot attach VM\n"); return; } - + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorAccountCreated","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -8014,21 +8018,21 @@ static void account_creator_activate_account(LinphoneAccountCreator *creator, Li ms_error("cannot attach VM\n"); return; } - + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorAccountActivated","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -8040,21 +8044,21 @@ static void account_creator_link_phone_number_with_account(LinphoneAccountCreato ms_error("cannot attach VM\n"); return; } - + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorAccountLinkedWithPhoneNumber","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -8092,21 +8096,47 @@ static void account_creator_is_account_linked(LinphoneAccountCreator *creator, L ms_error("cannot attach VM\n"); return; } - + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorIsAccountLinked","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); + env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); +} + +static void account_creator_is_phone_number_used(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status, const char *resp) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); + jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); + if (listener == NULL) { + ms_error("account_creator_response() notification without listener"); + return ; + } + + LinphoneCore *lc = (LinphoneCore *)creator->core; + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onAccountCreatorIsPhoneNumberUsed","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); + env->DeleteLocalRef(clazz); + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -8118,21 +8148,21 @@ static void account_creator_is_account_activated(LinphoneAccountCreator *creator ms_error("cannot attach VM\n"); return; } - + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorIsAccountActivated","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -8144,21 +8174,21 @@ static void account_creator_phone_account_recovered(LinphoneAccountCreator *crea ms_error("cannot attach VM\n"); return; } - + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); jobject listener = (jobject) linphone_account_creator_cbs_get_user_data(cbs); if (listener == NULL) { ms_error("account_creator_response() notification without listener"); return ; } - + LinphoneCore *lc = (LinphoneCore *)creator->core; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); - + jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onAccountCreatorPhoneAccountRecovered","(Lorg/linphone/core/LinphoneAccountCreator;Lorg/linphone/core/LinphoneAccountCreator$Status;)V"); env->DeleteLocalRef(clazz); - + jobject statusObject = env->CallStaticObjectMethod(ljb->accountCreatorStatusClass, ljb->accountCreatorStatusFromIntId, (jint)status); env->CallVoidMethod(listener, method, getAccountCreator(env, creator), statusObject); } @@ -8190,6 +8220,7 @@ extern "C" void Java_org_linphone_core_LinphoneAccountCreatorImpl_setListener(JN linphone_account_creator_cbs_set_activate_phone_number_link(cbs, account_creator_activate_phone_number_link); linphone_account_creator_cbs_set_is_account_activated(cbs, account_creator_is_account_activated); linphone_account_creator_cbs_set_recover_phone_account(cbs, account_creator_phone_account_recovered); + linphone_account_creator_cbs_set_is_phone_number_used(cbs, account_creator_is_phone_number_used); } extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_setUsername(JNIEnv *env, jobject thiz, jlong ptr, jstring jusername) { @@ -8258,6 +8289,14 @@ extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_setActivationC return (jint) status; } +extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_setLanguage(JNIEnv *env, jobject thiz, jlong ptr, jstring jlang) { + const char *lang = GetStringUTFChars(env, jlang); + LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr; + LinphoneAccountCreatorStatus status = linphone_account_creator_set_language(account_creator, lang); + ReleaseStringUTFChars(env, jlang, lang); + return (jint) status; +} + extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_setTransport(JNIEnv *env, jobject thiz, jlong ptr, jint jtransport) { LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr; LinphoneAccountCreatorStatus status = linphone_account_creator_set_transport(account_creator, (LinphoneTransportType)jtransport); @@ -8346,6 +8385,11 @@ extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_isAccountLinke return (jint) linphone_account_creator_is_account_linked(account_creator); } +extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_isPhoneNumberUsed(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr; + return (jint) linphone_account_creator_is_phone_number_used(account_creator); +} + extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_isAccountActivated(JNIEnv *env, jobject thiz, jlong ptr) { LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr; return (jint) linphone_account_creator_is_account_activated(account_creator); @@ -8433,4 +8477,4 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getTlsKeyPath(JNIEnv } else { return NULL; } -} \ No newline at end of file +} diff --git a/coreapi/misc.c b/coreapi/misc.c index e0acd816d..7b16e4f91 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1862,6 +1862,7 @@ static void _create_ice_check_lists_and_parse_ice_attributes(LinphoneCall *call, const char *addr = NULL; int port = 0; int componentID = 0; + int remote_family; int family; int i, j; @@ -1910,9 +1911,12 @@ static void _create_ice_check_lists_and_parse_ice_attributes(LinphoneCall *call, /* If we receive a re-invite and we finished ICE processing on our side, use the candidates given by the remote. */ ice_check_list_unselect_valid_pairs(cl); } - if (strchr(remote_candidate->addr, ':') != NULL) family = AF_INET6; + if (strchr(remote_candidate->addr, ':') != NULL) remote_family = AF_INET6; + else remote_family = AF_INET; + if (strchr(addr, ':') != NULL) family = AF_INET6; else family = AF_INET; - ice_add_losing_pair(cl, j + 1, family, remote_candidate->addr, remote_candidate->port, addr, port); + + ice_add_losing_pair(cl, j + 1, remote_family, remote_candidate->addr, remote_candidate->port, family, addr, port); losing_pairs_added = TRUE; } if (losing_pairs_added == TRUE) ice_check_list_check_completed(cl); diff --git a/coreapi/nat_policy.c b/coreapi/nat_policy.c index c80a1dd4f..2d0826ef9 100644 --- a/coreapi/nat_policy.c +++ b/coreapi/nat_policy.c @@ -39,7 +39,9 @@ static void linphone_nat_policy_destroy(LinphoneNatPolicy *policy) { if (policy->stun_server) belle_sip_free(policy->stun_server); if (policy->stun_server_username) belle_sip_free(policy->stun_server_username); if (policy->stun_addrinfo) bctbx_freeaddrinfo(policy->stun_addrinfo); - //if (policy->stun_resolver_context) sal_resolve_cancel(policy->stun_resolver_context); + if (policy->stun_resolver_context) { + sal_resolve_cancel(policy->stun_resolver_context); + } } static bool_t linphone_nat_policy_stun_server_activated(LinphoneNatPolicy *policy) { @@ -213,7 +215,10 @@ static void stun_server_resolved(LinphoneNatPolicy *policy, const char *name, st ms_warning("Stun server resolution failed."); } policy->stun_addrinfo = addrinfo; - policy->stun_resolver_context = NULL; + if (policy->stun_resolver_context){ + sal_resolver_context_unref(policy->stun_resolver_context); + policy->stun_resolver_context = NULL; + } } void linphone_nat_policy_resolve_stun_server(LinphoneNatPolicy *policy) { @@ -229,6 +234,7 @@ void linphone_nat_policy_resolve_stun_server(LinphoneNatPolicy *policy) { int family = AF_INET; if (linphone_core_ipv6_enabled(policy->lc) == TRUE) family = AF_INET6; policy->stun_resolver_context = sal_resolve(policy->lc->sal, service, "udp", host, port, family, (SalResolverCallback)stun_server_resolved, policy); + if (policy->stun_resolver_context) sal_resolver_context_ref(policy->stun_resolver_context); } } } diff --git a/coreapi/private.h b/coreapi/private.h index 831274bbe..5f70847b0 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -428,7 +428,7 @@ void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneE 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); void linphone_friend_close_subscriptions(LinphoneFriend *lf); void _linphone_friend_release(LinphoneFriend *lf); @@ -653,8 +653,7 @@ struct _LinphoneProxyConfig /*use to check if server config has changed between edit() and done()*/ LinphoneAddress *saved_proxy; LinphoneAddress *saved_identity; - int saved_expires; - bool_t saved_sendregister; + bool_t register_changed; bool_t unused[3]; /*---*/ LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/ @@ -1020,7 +1019,7 @@ struct _LinphoneCore bool_t send_call_stats_periodical_updates; bool_t forced_ice_relay; bool_t short_turn_refresh; - + char localip[LINPHONE_IPADDR_SIZE]; int device_rotation; int max_calls; @@ -1060,14 +1059,14 @@ struct _LinphoneCore jmethodID multicast_lock_release_id; #endif LinphoneVcardContext *vcard_context; - + /*for tests only*/ bool_t zrtp_not_available_simulation; - + /* string for TLS auth instead of path to files */ char *tls_cert; char *tls_key; - + /*default resource list server*/ LinphoneAddress *default_rls_addr; }; @@ -1087,6 +1086,7 @@ struct _LinphoneEvent{ bool_t terminating; bool_t is_out_of_dialog_op; /*used for out of dialog notify*/ bool_t internal; + bool_t oneshot; }; BELLE_SIP_DECLARE_VPTR(LinphoneEvent); @@ -1176,7 +1176,7 @@ void _linphone_core_codec_config_write(LinphoneCore *lc); #define LINPHONE_MAX_CALL_HISTORY_UNLIMITED (-1) #ifndef LINPHONE_MAX_CALL_HISTORY_SIZE #ifdef SQLITE_STORAGE_ENABLED - #define LINPHONE_MAX_CALL_HISTORY_SIZE LINPHONE_MAX_CALL_HISTORY_UNLIMITED + #define LINPHONE_MAX_CALL_HISTORY_SIZE LINPHONE_MAX_CALL_HISTORY_UNLIMITED #else #define LINPHONE_MAX_CALL_HISTORY_SIZE 30 #endif @@ -1335,7 +1335,7 @@ struct _LinphoneAccountCreatorCbs { LinphoneAccountCreatorCbsStatusCb create_account; LinphoneAccountCreatorCbsStatusCb activate_account; LinphoneAccountCreatorCbsStatusCb is_account_activated; - + LinphoneAccountCreatorCbsStatusCb is_phone_number_used; LinphoneAccountCreatorCbsStatusCb link_phone_number_with_account; LinphoneAccountCreatorCbsStatusCb activate_phone_number_link; LinphoneAccountCreatorCbsStatusCb recover_phone_account; @@ -1363,6 +1363,7 @@ struct _LinphoneAccountCreator { char *activation_code; char *ha1; char *phone_country_code; + char *language; }; BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index a3b963a43..f339e5938 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -29,7 +29,6 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) /*store current config related to server location*/ static void linphone_proxy_config_store_server_config(LinphoneProxyConfig* cfg) { - cfg->saved_sendregister = cfg->reg_sendregister; if (cfg->saved_identity) linphone_address_destroy(cfg->saved_identity); if (cfg->identity_address) cfg->saved_identity = linphone_address_clone(cfg->identity_address); @@ -355,11 +354,13 @@ bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *cfg){ } void linphone_proxy_config_enableregister(LinphoneProxyConfig *cfg, bool_t val){ + if (val != cfg->reg_sendregister) cfg->register_changed = TRUE; cfg->reg_sendregister=val; } void linphone_proxy_config_set_expires(LinphoneProxyConfig *cfg, int val){ if (val<0) val=600; + if (val != cfg->expires) cfg->register_changed = TRUE; cfg->expires=val; } @@ -379,8 +380,7 @@ void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){ if (cfg->publish && cfg->long_term_event){ linphone_event_pause_publish(cfg->long_term_event); } - /*stop refresher in any case*/ - linphone_proxy_config_pause_register(cfg); + /*Don't stop refresher*/ } void linphone_proxy_config_apply(LinphoneProxyConfig *cfg,LinphoneCore *lc){ @@ -638,11 +638,11 @@ char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, c LinphoneDialPlan dialplan = *linphone_dial_plan_by_ccc(tmpproxy->dial_prefix); //copy dial plan; char * flatten=flatten_number(username); ms_debug("Flattened number is '%s' for '%s'",flatten, username); - + if (tmpproxy->dial_prefix){ if (strcmp(tmpproxy->dial_prefix,dialplan.ccc) != 0){ //probably generic dialplan, preserving proxy dial prefix - strcpy(dialplan.ccc,tmpproxy->dial_prefix); + strncpy(dialplan.ccc,tmpproxy->dial_prefix,sizeof(dialplan.ccc)); } } /*if proxy has a dial prefix, modify phonenumber accordingly*/ @@ -783,9 +783,12 @@ int linphone_proxy_config_done(LinphoneProxyConfig *cfg) } cfg->commit = TRUE; } - if ((cfg->saved_sendregister != cfg->reg_sendregister) - || (cfg->saved_expires != cfg->expires)){ + if (cfg->register_changed){ cfg->commit = TRUE; + cfg->register_changed = FALSE; + } + if (cfg->commit){ + linphone_proxy_config_pause_register(cfg); } if (linphone_proxy_config_compute_publish_params_hash(cfg)) { @@ -916,6 +919,7 @@ void linphone_proxy_config_set_contact_parameters(LinphoneProxyConfig *cfg, cons if (contact_params){ cfg->contact_params=ms_strdup(contact_params); } + cfg->register_changed = TRUE; } void linphone_proxy_config_set_contact_uri_parameters(LinphoneProxyConfig *cfg, const char *contact_uri_params){ @@ -926,6 +930,7 @@ void linphone_proxy_config_set_contact_uri_parameters(LinphoneProxyConfig *cfg, if (contact_uri_params){ cfg->contact_uri_params=ms_strdup(contact_uri_params); } + cfg->register_changed = TRUE; } const char *linphone_proxy_config_get_contact_parameters(const LinphoneProxyConfig *cfg){ @@ -949,6 +954,7 @@ const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, co void linphone_proxy_config_set_custom_header(LinphoneProxyConfig *cfg, const char *header_name, const char *header_value){ cfg->sent_headers=sal_custom_header_append(cfg->sent_headers, header_name, header_value); + cfg->register_changed = TRUE; } int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 92a402a3c..ecf301ca7 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -264,7 +264,6 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { LinphoneContent *content; - int expires = -1; size_t offset = 0; size_t size = 2048; char * buffer; @@ -357,7 +356,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, collector_uri = ms_strdup_printf("sip:%s", linphone_proxy_config_get_domain(call->dest_proxy)); } request_uri = linphone_address_new(collector_uri); - lev=linphone_core_create_publish(call->core, request_uri, "vq-rtcpxr", expires); + lev = linphone_core_create_one_shot_publish(call->core, request_uri, "vq-rtcpxr"); /* Special exception for quality report PUBLISH: if the collector_uri has any transport related parameters * (port, transport, maddr), then it is sent directly. * Otherwise it is routed as any LinphoneEvent publish, following proxy config policy. @@ -370,7 +369,6 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, } if (linphone_event_send_publish(lev, content) != 0){ - linphone_event_unref(lev); lev=NULL; ret=4; } else { diff --git a/coreapi/xmlrpc.c b/coreapi/xmlrpc.c index 5076a9391..bd74447ad 100644 --- a/coreapi/xmlrpc.c +++ b/coreapi/xmlrpc.c @@ -118,7 +118,7 @@ static void format_request(LinphoneXmlRpcRequest *request) { err = xmlTextWriterWriteElement(writer, (const xmlChar *)"int", (const xmlChar *)si); break; case LinphoneXmlRpcArgString: - err = xmlTextWriterWriteElement(writer, (const xmlChar *)"string", (const xmlChar *)arg->data.s); + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"string", arg->data.s ? (const xmlChar *)arg->data.s : (const xmlChar *)""); break; } if (err >= 0) { diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 2140af358..2137c230f 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -115,9 +115,11 @@ apply_compile_flags(DAEMON_PIPETEST_SOURCE_FILES "CPP" "C") add_executable(linphone-daemon ${DAEMON_SOURCE_FILES}) target_include_directories(linphone-daemon PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(linphone-daemon ${LINPHONE_LIBS_FOR_TOOLS} ${MEDIASTREAMER2_LIBRARIES}) +set_target_properties(linphone-daemon PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") add_executable(linphone-daemon-pipetest ${DAEMON_PIPETEST_SOURCE_FILES}) target_link_libraries(linphone-daemon-pipetest ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES}) +set_target_properties(linphone-daemon-pipetest PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") set(INSTALL_TARGETS linphone-daemon linphone-daemon-pipetest) diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index 3e36665b5..ae3e0d2d0 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -95,6 +95,7 @@ endif() set_target_properties(linphone-gtk PROPERTIES OUTPUT_NAME linphone LINKER_LANGUAGE CXX) target_include_directories(linphone-gtk PUBLIC ${GTK2_INCLUDE_DIRS} ${INTL_INCLUDE_DIRS}) target_link_libraries(linphone-gtk ${LINPHONE_LIBS_FOR_TOOLS} ${GTK2_LIBRARIES} ${BCTOOLBOX_CORE_LIBRARIES} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES}) +set_target_properties(linphone-gtk PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") if(INTL_FOUND) target_link_libraries(linphone-gtk ${INTL_LIBRARIES}) endif() diff --git a/gtk/main.c b/gtk/main.c index 4fe5ff523..333a858ea 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1022,13 +1022,7 @@ void linphone_gtk_used_identity_changed(GtkWidget *w){ void on_proxy_refresh_button_clicked(GtkWidget *w){ LinphoneCore *lc=linphone_gtk_get_core(); - bctbx_list_t const *item=linphone_core_get_proxy_config_list(lc); - while (item != NULL) { - LinphoneProxyConfig *lpc=(LinphoneProxyConfig*)item->data; - linphone_proxy_config_edit(lpc); - linphone_proxy_config_done(lpc); - item = item->next; - } + linphone_core_refresh_registers(lc); } static gboolean grab_focus(GtkWidget *w){ diff --git a/include/sal/sal.h b/include/sal/sal.h index 2a12a2444..b07f2ef81 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -838,11 +838,13 @@ void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t ipl typedef void (*SalResolverCallback)(void *data, const char *name, struct addrinfo *ai_list); -typedef struct SalResolverContext SalResolverContext; +typedef struct SalResolverContext SalResolverContext; +#define sal_resolver_context_ref(obj) belle_sip_object_ref(obj) +#define sal_resolver_context_unref(obj) belle_sip_object_unref(obj) LINPHONE_PUBLIC SalResolverContext * sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data); LINPHONE_PUBLIC SalResolverContext * sal_resolve(Sal *sal, const char *service, const char *transport, const char *name, int port, int family, SalResolverCallback cb, void *data); -//void sal_resolve_cancel(Sal *sal, SalResolverContext *ctx); +void sal_resolve_cancel(SalResolverContext *ctx); SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name, const char *value); const char *sal_custom_header_find(const SalCustomHeader *ch, const char *name); diff --git a/java/common/org/linphone/core/LinphoneAccountCreator.java b/java/common/org/linphone/core/LinphoneAccountCreator.java index 298a4acb9..981c52b9a 100644 --- a/java/common/org/linphone/core/LinphoneAccountCreator.java +++ b/java/common/org/linphone/core/LinphoneAccountCreator.java @@ -31,8 +31,9 @@ public interface LinphoneAccountCreator { void onAccountCreatorIsAccountActivated(LinphoneAccountCreator accountCreator, Status status); void onAccountCreatorPhoneAccountRecovered(LinphoneAccountCreator accountCreator, Status status); void onAccountCreatorIsAccountLinked(LinphoneAccountCreator accountCreator, Status status); + void onAccountCreatorIsPhoneNumberUsed(LinphoneAccountCreator accountCreator, Status status); } - + public static class Status { static private Vector values = new Vector(); private final int mValue; @@ -59,20 +60,24 @@ public interface LinphoneAccountCreator { public final static Status PhoneNumberInvalid = new Status(17, "PhoneNumberInvalid"); public final static Status PhoneNumberTooShort = new Status(18, "PhoneNumberTooShort"); public final static Status PhoneNumberTooLong = new Status(19, "PhoneNumberTooLong"); - public final static Status PasswordTooShort = new Status(20, "PasswordTooShort"); - public final static Status PasswordTooLong = new Status(21, "PasswordTooLong"); - public final static Status DomainInvalid = new Status(22, "DomainInvalid"); - public final static Status RouteInvalid = new Status(23, "RouteInvalid"); - public final static Status DisplayNameInvalid = new Status(24, "DisplayNameInvalid"); - public final static Status TransportNotSupported = new Status(25, "TransportNotSupported"); - public final static Status CountryCodeInvalid = new Status(26, "CountryCodeInvalid"); - + public final static Status PhoneNumberUsedAccount = new Status(20, "PhoneNumberUsed"); + public final static Status PhoneNumberUsedAlias = new Status(21, "PhoneNumberUsed"); + public final static Status PhoneNumberNotUsed = new Status(22, "PhoneNumberNotUsed"); + public final static Status PasswordTooShort = new Status(23, "PasswordTooShort"); + public final static Status PasswordTooLong = new Status(24, "PasswordTooLong"); + public final static Status DomainInvalid = new Status(25, "DomainInvalid"); + public final static Status RouteInvalid = new Status(26, "RouteInvalid"); + public final static Status DisplayNameInvalid = new Status(27, "DisplayNameInvalid"); + public final static Status TransportNotSupported = new Status(28, "TransportNotSupported"); + public final static Status CountryCodeInvalid = new Status(29, "CountryCodeInvalid"); + public final static Status ErrorServer = new Status(30, "ErrorServer"); + private Status(int value, String stringValue) { mValue = value; values.addElement(this); mStringValue = stringValue; } - + public static Status fromInt(int value) { for (int i=0; i < values.size(); i++) { Status state = (Status) values.elementAt(i); @@ -80,71 +85,75 @@ public interface LinphoneAccountCreator { } throw new RuntimeException("Status not found [" + value + "]"); } - + public String toString() { return mStringValue; } - + public int toInt() { return mValue; } } - + void setListener(LinphoneAccountCreatorListener listener); - + Status setUsername(String username); - + String getUsername(); - + Status setPhoneNumber(String phoneNumber, String countryCode); - + String getPhoneNumber(); - + Status setPassword(String password); - + String getPassword(); Status setHa1(String ha1); String getHa1(); - + Status setActivationCode(String activationCode); - + + Status setLanguage(String lang); + Status setTransport(TransportType transport); - + TransportType getTransport(); - + Status setDomain(String domain); - + String getDomain(); - + Status setRoute(String route); - + String getRoute(); - + Status setDisplayName(String displayName); - + String getDisplayName(); - + Status setEmail(String email); - + String getEmail(); - + Status isAccountUsed(); - + Status createAccount(); - + Status activateAccount(); - + Status isAccountActivated(); - + Status linkPhoneNumberWithAccount(); - + Status activatePhoneNumberLink(); Status isAccountLinked(); + Status isPhoneNumberUsed(); + Status recoverPhoneAccount(); - + LinphoneProxyConfig configure(); } diff --git a/java/common/org/linphone/core/LinphoneCallStats.java b/java/common/org/linphone/core/LinphoneCallStats.java index 4f56f9ec3..e7d238f26 100644 --- a/java/common/org/linphone/core/LinphoneCallStats.java +++ b/java/common/org/linphone/core/LinphoneCallStats.java @@ -101,6 +101,22 @@ public interface LinphoneCallStats { } } + static public enum LinphoneAddressFamily { + INET(0), + INET_6(1), + UNSPEC(2); + + private int value; + + LinphoneAddressFamily(int v) { + value = v; + } + + public int getInt() { + return value; + } + } + /** * Get the stats media type * @return MediaType @@ -191,4 +207,10 @@ public interface LinphoneCallStats { * @return The name of decoder */ public String getDecoderName(PayloadType pl); + + /** + * Get family of remote ip + * @return enum LinphoneAddressFamily + */ + public int getIpFamilyOfRemote(); } diff --git a/java/impl/org/linphone/core/LinphoneAccountCreatorImpl.java b/java/impl/org/linphone/core/LinphoneAccountCreatorImpl.java index d47cedc7e..b632199ed 100644 --- a/java/impl/org/linphone/core/LinphoneAccountCreatorImpl.java +++ b/java/impl/org/linphone/core/LinphoneAccountCreatorImpl.java @@ -21,16 +21,16 @@ import org.linphone.core.LinphoneAddress.TransportType; public class LinphoneAccountCreatorImpl implements LinphoneAccountCreator { protected long nativePtr; - + protected LinphoneAccountCreatorImpl(long aNativePtr) { nativePtr = aNativePtr; } - + private native long newLinphoneAccountCreator(long lc, String url); public LinphoneAccountCreatorImpl(LinphoneCore lc, String url) { nativePtr = newLinphoneAccountCreator(((LinphoneCoreImpl)lc).nativePtr, url); } - + public long getNativePtr() { return nativePtr; } @@ -45,7 +45,7 @@ public class LinphoneAccountCreatorImpl implements LinphoneAccountCreator { public void setListener(LinphoneAccountCreatorListener listener) { setListener(nativePtr, listener); } - + private native int setUsername(long ptr, String username); @Override public Status setUsername(String username) { @@ -100,6 +100,12 @@ public class LinphoneAccountCreatorImpl implements LinphoneAccountCreator { return Status.fromInt(setActivationCode(nativePtr, activationCode)); } + private native int setLanguage(long ptr, String lang); + @Override + public Status setLanguage(String lang) { + return Status.fromInt(setLanguage(nativePtr, lang)); + } + private native int setTransport(long ptr, int transport); @Override public Status setTransport(TransportType transport) { @@ -141,7 +147,7 @@ public class LinphoneAccountCreatorImpl implements LinphoneAccountCreator { public Status setDisplayName(String displayName) { return Status.fromInt(setDisplayName(nativePtr, displayName)); } - + private native String getDisplayName(long ptr); @Override public String getDisplayName() { @@ -159,19 +165,19 @@ public class LinphoneAccountCreatorImpl implements LinphoneAccountCreator { public String getEmail() { return getEmail(nativePtr); } - + private native int isAccountUsed(long ptr); @Override public Status isAccountUsed() { return Status.fromInt(isAccountUsed(nativePtr)); } - + private native int createAccount(long ptr); @Override public Status createAccount() { return Status.fromInt(createAccount(nativePtr)); } - + private native int activateAccount(long ptr); @Override public Status activateAccount() { @@ -183,31 +189,37 @@ public class LinphoneAccountCreatorImpl implements LinphoneAccountCreator { public Status isAccountLinked() { return Status.fromInt(isAccountLinked(nativePtr)); } - + + private native int isPhoneNumberUsed(long ptr); + @Override + public Status isPhoneNumberUsed() { + return Status.fromInt(isPhoneNumberUsed(nativePtr)); + } + private native int isAccountActivated(long ptr); @Override public Status isAccountActivated() { return Status.fromInt(isAccountActivated(nativePtr)); } - + private native int linkPhoneNumberWithAccount(long ptr); @Override public Status linkPhoneNumberWithAccount() { return Status.fromInt(linkPhoneNumberWithAccount(nativePtr)); } - + private native int activatePhoneNumberLink(long ptr); @Override public Status activatePhoneNumberLink() { return Status.fromInt(activatePhoneNumberLink(nativePtr)); } - + private native int recoverPhoneAccount(long ptr); @Override public Status recoverPhoneAccount() { return Status.fromInt(recoverPhoneAccount(nativePtr)); } - + private native LinphoneProxyConfig configure(long ptr); @Override public LinphoneProxyConfig configure() { diff --git a/java/impl/org/linphone/core/LinphoneCallStatsImpl.java b/java/impl/org/linphone/core/LinphoneCallStatsImpl.java index 3c68bffd7..add4f982b 100644 --- a/java/impl/org/linphone/core/LinphoneCallStatsImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallStatsImpl.java @@ -52,6 +52,7 @@ class LinphoneCallStatsImpl implements LinphoneCallStats { private native String getEncoderName(long nativeStatsPtr, long nativeCallPtr, long payloadPtr); private native String getDecoderName(long nativeStatsPtr, long nativeCallPtr, long payloadPtr); private native void updateStats(long nativeCallPtr, int mediaType); + private native int getIpFamilyOfRemote(long nativeStatsPtr); protected LinphoneCallStatsImpl(long nativeCallPtr, long nativeStatsPtr) { nativePtr = nativeStatsPtr; @@ -67,7 +68,7 @@ class LinphoneCallStatsImpl implements LinphoneCallStats { roundTripDelay = getRoundTripDelay(nativeStatsPtr); latePacketsCumulativeNumber = getLatePacketsCumulativeNumber(nativeStatsPtr, nativeCallPtr); jitterBufferSize = getJitterBufferSize(nativeStatsPtr); - + } protected void updateRealTimeStats(LinphoneCall call){ @@ -139,4 +140,8 @@ class LinphoneCallStatsImpl implements LinphoneCallStats { return ""; return getDecoderName(nativePtr, nativeCPtr, ((PayloadTypeImpl)pl).nativePtr); } + + public int getIpFamilyOfRemote() { + return getIpFamilyOfRemote(nativePtr); + } } diff --git a/mediastreamer2 b/mediastreamer2 index 8b4fca52b..0b60a94e9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 8b4fca52b0e6939f908a33da9952cf4a8c862a07 +Subproject commit 0b60a94e940b8b0174fe30ec0f25037b5abe87fb diff --git a/oRTP b/oRTP index 5d58ed7be..01540c8ef 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 5d58ed7bead312e77bd6f0ac0328352250dd1349 +Subproject commit 01540c8efcf6773b97239c9576af179cf1630b0b diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index 1eb8f21cf..4e134789b 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -267,10 +267,10 @@ if (NOT ANDROID AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") if(IOS) set_source_files_properties(${IOS_RESOURCES_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) add_executable(liblinphone_tester MACOSX_BUNDLE ${IOS_RESOURCES_FILES} ${SOURCE_FILES_C} ${SOURCE_FILES_OBJC}) - set_target_properties(liblinphone_tester PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") else() add_executable(liblinphone_tester ${SOURCE_FILES_C} ${SOURCE_FILES_OBJC}) endif() + set_target_properties(liblinphone_tester PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") set_target_properties(liblinphone_tester PROPERTIES LINKER_LANGUAGE CXX) target_include_directories(liblinphone_tester PUBLIC ${BCTOOLBOX_TESTER_INCLUDE_DIRS}) target_link_libraries(liblinphone_tester ${LINPHONE_LIBS_FOR_TOOLS} ${OTHER_LIBS_FOR_TESTER}) diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 74549b3ff..1e818c0b8 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -5125,6 +5125,33 @@ static void call_from_zrtp_to_plain_rtp(void){ call_with_encryption_mandatory(TRUE); } +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); + linphone_core_manager_start(pauline, TRUE); + + if (BC_ASSERT_TRUE(call(marie,pauline))){ + check_media_direction(marie, linphone_core_get_current_call(marie->lc), lcs, LinphoneMediaDirectionSendRecv, LinphoneMediaDirectionInvalid); + + liblinphone_tester_check_rtcp(marie,pauline); + end_call(marie,pauline); + } + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + bctbx_list_free(lcs); + + }else ms_warning("Test skipped, dual stack not available"); +} + static void v6_call_over_nat_64(void){ LinphoneCoreManager* marie; LinphoneCoreManager* pauline; @@ -5159,7 +5186,49 @@ static void call_with_ice_in_ipv4_with_v6_enabled(void) { marie = linphone_core_manager_new("marie_v4proxy_rc"); pauline = linphone_core_manager_new("pauline_v4proxy_rc"); - _call_with_ice_base(pauline,marie,TRUE,TRUE,TRUE,FALSE); + _call_with_ice_base(marie,pauline,TRUE,TRUE,TRUE,TRUE); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + } else ms_warning("Test skipped, need both ipv6 and v4 available"); +} + +static void call_with_ice_ipv4_to_ipv6(void) { + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + + if (liblinphone_tester_ipv4_available() && liblinphone_tester_ipv6_available()){ + marie = linphone_core_manager_new("marie_v4proxy_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); + + _call_with_ice_base(marie,pauline,TRUE,TRUE,TRUE,TRUE); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + } else ms_warning("Test skipped, need both ipv6 and v4 available"); +} + +static void call_with_ice_ipv6_to_ipv4(void) { + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + + if (liblinphone_tester_ipv4_available() && liblinphone_tester_ipv6_available()){ + marie = linphone_core_manager_new("marie_rc"); + pauline = linphone_core_manager_new("pauline_v4proxy_rc"); + + _call_with_ice_base(marie, pauline,TRUE,TRUE,TRUE,TRUE); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + } else ms_warning("Test skipped, need both ipv6 and v4 available"); +} + +static void call_with_ice_ipv6_to_ipv6(void) { + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + + if (liblinphone_tester_ipv4_available() && liblinphone_tester_ipv6_available()){ + marie = linphone_core_manager_new("marie_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); + + _call_with_ice_base(marie, pauline,TRUE,TRUE,TRUE,TRUE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } else ms_warning("Test skipped, need both ipv6 and v4 available"); @@ -5180,8 +5249,12 @@ test_t call_tests[] = { TEST_NO_TAG("Call with http proxy", call_with_http_proxy), TEST_NO_TAG("Call with timeouted bye", call_with_timeouted_bye), TEST_NO_TAG("Direct call over IPv6", direct_call_over_ipv6), + TEST_NO_TAG("Call IPv6 to IPv4 without relay", v6_to_v4_call_without_relay), TEST_NO_TAG("IPv6 call over NAT64", v6_call_over_nat_64), - TEST_NO_TAG("Call with ICE in IPv4 with IPv6 enabled", call_with_ice_in_ipv4_with_v6_enabled), + TEST_ONE_TAG("Call with ICE in IPv4 with IPv6 enabled", call_with_ice_in_ipv4_with_v6_enabled, "ICE"), + TEST_ONE_TAG("Call with ICE IPv4 to IPv6", call_with_ice_ipv4_to_ipv6, "ICE"), + TEST_ONE_TAG("Call with ICE IPv6 to IPv4", call_with_ice_ipv6_to_ipv4, "ICE"), + TEST_ONE_TAG("Call with ICE IPv6 to IPv6", call_with_ice_ipv6_to_ipv6, "ICE"), TEST_NO_TAG("Outbound call with multiple proxy possible", call_outbound_with_multiple_proxy), TEST_NO_TAG("Audio call recording", audio_call_recording_test), #if 0 /* not yet activated because not implemented */ diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c index e60b28396..bbdc42abf 100644 --- a/tester/presence_server_tester.c +++ b/tester/presence_server_tester.c @@ -48,11 +48,16 @@ static void simple(void) { LinphonePresenceModel *pauline_presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL); LinphoneFriend* f = linphone_core_create_friend_with_address(marie->lc, get_identity(pauline)); LinphonePresenceActivity *activity = NULL; + LinphoneCoreVTable *vtable = linphone_core_v_table_new(); + vtable->publish_state_changed = linphone_publish_state_changed; + _linphone_core_add_listener(pauline->lc, vtable, TRUE, TRUE ); + 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)); linphone_friend_enable_subscribes(f, TRUE); linphone_friend_set_inc_subscribe_policy(f,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/ @@ -66,10 +71,16 @@ static void simple(void) { BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner, int, "%d"); } + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,2)); + linphone_friend_unref(f); 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 diff --git a/tester/presence_tester.c b/tester/presence_tester.c index 29d32d171..823dd19e6 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -149,7 +149,7 @@ static void simple_publish_with_expire(int expires) { proxy = linphone_core_get_default_proxy_config(marie->lc); linphone_proxy_config_edit(proxy); - if (expires >0) { + if (expires > 0) { linphone_proxy_config_set_publish_expires(proxy,expires); } linphone_proxy_config_enable_publish(proxy,TRUE); @@ -192,7 +192,7 @@ static void simple_publish_with_expire(int expires) { BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,4)); linphone_core_manager_stop(marie); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,2,int,"%i"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,3,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/ BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i"); linphone_core_manager_destroy(marie); } @@ -564,8 +564,8 @@ test_t presence_tests[] = { TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"), TEST_ONE_TAG("Simple Subscribe with early NOTIFY", simple_subscribe_with_early_notify,"presence"), TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc), - TEST_ONE_TAG("Simple Publish", simple_publish, "LeaksMemory"), - TEST_ONE_TAG("Simple Publish with expires", publish_with_expires, "LeaksMemory"), + TEST_NO_TAG("Simple Publish", simple_publish), + TEST_NO_TAG("Simple Publish with expires", publish_with_expires), /*TEST_ONE_TAG("Call with presence", call_with_presence, "LeaksMemory"),*/ TEST_NO_TAG("Unsubscribe while subscribing", unsubscribe_while_subscribing), TEST_NO_TAG("Presence information", presence_information), diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c index ad6563ecc..5a15109c1 100644 --- a/tester/quality_reporting_tester.c +++ b/tester/quality_reporting_tester.c @@ -413,6 +413,8 @@ static void quality_reporting_interval_report_video_and_rtt(void) { } end_call(marie, pauline); + /*wait for publish triggered by the end of call to be completed*/ + wait_for_until(marie->lc,pauline->lc,NULL,0,3000); } linphone_call_params_destroy(marie_params); diff --git a/tester/register_tester.c b/tester/register_tester.c index 9f8f64430..ed32e2b80 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -240,21 +240,18 @@ static void change_expires(void){ proxy_config = linphone_core_get_default_proxy_config(lcm->lc); linphone_proxy_config_edit(proxy_config); - reset_counters(counters); /*clear stats*/ /*nothing is supposed to arrive until done*/ BC_ASSERT_FALSE(wait_for_until(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationCleared,1,3000)); linphone_proxy_config_set_expires(proxy_config,3); - + reset_counters(counters); /*clear stats*/ linphone_proxy_config_done(proxy_config); BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationOk,1)); /*wait 2s without receive refresh*/ BC_ASSERT_FALSE(wait_for_until(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationOk,2,2000)); /* now, it should be ok*/ BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationOk,2)); - - linphone_core_manager_destroy(lcm); } @@ -584,6 +581,26 @@ static void transport_change(void){ } } +static void transport_dont_bind(void){ + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + stats* counters = &pauline->stat; + LCSipTransports tr; + + memset(&tr, 0, sizeof(tr)); + tr.udp_port = 0; + tr.tcp_port = LC_SIP_TRANSPORT_DONTBIND; + tr.tls_port = LC_SIP_TRANSPORT_DONTBIND; + + linphone_core_set_sip_transports(pauline->lc, &tr); + BC_ASSERT_TRUE(wait_for_until(pauline->lc,pauline->lc,&counters->number_of_LinphoneRegistrationOk,2,9000)); + memset(&tr, 0, sizeof(tr)); + linphone_core_get_sip_transports_used(pauline->lc, &tr); + BC_ASSERT_EQUAL(tr.udp_port, 0, int, "%i"); + BC_ASSERT_EQUAL(tr.tcp_port, LC_SIP_TRANSPORT_DONTBIND, int, "%i"); + BC_ASSERT_EQUAL(tr.tls_port, LC_SIP_TRANSPORT_DONTBIND, int, "%i"); + linphone_core_manager_destroy(pauline); +} + static void proxy_transport_change(void){ LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; @@ -1126,6 +1143,7 @@ test_t register_tests[] = { TEST_NO_TAG("Register with refresh and send error", register_with_refresh_with_send_error), TEST_NO_TAG("Multi account", multiple_proxy), TEST_NO_TAG("Transport changes", transport_change), + TEST_NO_TAG("Transport configured with dontbind option", transport_dont_bind), TEST_NO_TAG("Proxy transport changes", proxy_transport_change), TEST_NO_TAG("Proxy transport changes with wrong address at first", proxy_transport_change_with_wrong_port), TEST_NO_TAG("Proxy transport changes with wrong address, giving up",proxy_transport_change_with_wrong_port_givin_up), diff --git a/tester/tester.c b/tester/tester.c index c48887034..2be8bbdec 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -59,6 +59,9 @@ const char* test_route="sip2.linphone.org"; const char *userhostsfile = "tester_hosts"; bool_t liblinphonetester_ipv6 = TRUE; bool_t liblinphonetester_show_account_manager_logs = FALSE; +int liblinphonetester_transport_timeout = 9000; /*milliseconds. it is set to such low value to workaround a problem with our Freebox v6 when connecting to Ipv6 addresses. + It was found that the freebox sometimes block SYN-ACK packets, which prevents connection to be succesful. + Thanks to the timeout, it will fallback to IPv4*/ const char *liblinphone_tester_mire_id="Mire: Mire (synthetic moving picture)"; @@ -158,6 +161,7 @@ LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, c chatdb = ms_strdup_printf("%s/messages-%p.db",bc_tester_get_writable_dir_prefix(),lc); linphone_core_enable_ipv6(lc, liblinphonetester_ipv6); + linphone_core_set_sip_transport_timeout(lc, liblinphonetester_transport_timeout); sal_enable_test_features(lc->sal,TRUE); sal_set_dns_user_hosts_file(lc->sal, dnsuserhostspath);