diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 8a53abdab..363ac54b6 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -526,7 +526,7 @@ static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { } if (reason != SalReasonNone){ - sal_error_info_init_to_null(&sei); + sal_error_info_reset(&sei); sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL); sal_call_decline_with_error_info(op, &sei,NULL); @@ -1092,10 +1092,9 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ - SalErrorInfo sei; + SalErrorInfo sei = { 0 }; const SalErrorInfo *p_sei; if (info == NULL){ - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL); p_sei = &sei; } else{ diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index f859b221e..3db9a73e8 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -567,16 +567,6 @@ const SalErrorInfo *sal_error_info_none(void){ return &none; } -void sal_error_info_init_to_null(SalErrorInfo *sei){ - sei->status_string = NULL; - sei->full_string = NULL; - sei->protocol = NULL; - sei->sub_sei = NULL; - sei->warnings = NULL; - sei->protocol_code=0; - sei->reason=SalReasonNone; -} - void sal_error_info_reset(SalErrorInfo *ei){ if (ei->status_string){ ms_free(ei->status_string); @@ -601,6 +591,7 @@ void sal_error_info_reset(SalErrorInfo *ei){ } ei->protocol_code=0; ei->reason=SalReasonNone; + ei->sub_sei = NULL; } void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol, int code, const char *status_string, const char *warning){ diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 26bcad581..ef1d4822d 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -269,7 +269,6 @@ static void call_received(SalOp *h){ LinphoneAddress *from_address_to_search_if_me=NULL; /*address used to know if I'm the caller*/ SalMediaDescription *md; const char * p_asserted_id; - SalErrorInfo sei; LinphoneErrorInfo *ei = NULL; /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ @@ -307,7 +306,7 @@ static void call_received(SalOp *h){ case LinphonePresenceActivityPermanentAbsence: alt_contact = linphone_presence_model_get_contact(lc->presence_model); if (alt_contact != NULL) { - sal_error_info_init_to_null(&sei); + SalErrorInfo sei = { 0 }; sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(h, &sei,alt_contact); ms_free(alt_contact); @@ -315,6 +314,7 @@ static void call_received(SalOp *h){ linphone_error_info_set(ei, NULL, LinphoneReasonMovedPermanently, 302, "Moved permanently", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); + sal_error_info_reset(&sei); return; } break; @@ -701,7 +701,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){ /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t is_update){ - SalErrorInfo sei; + SalErrorInfo sei = { 0 }; SalMediaDescription *rmd=sal_call_get_remote_media_description(op); call->defer_update = lp_config_get_int(lc->config, "sip", "defer_update_default", FALSE); @@ -739,7 +739,6 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t case LinphoneCallUpdating: case LinphoneCallPausing: case LinphoneCallResuming: - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonInternalError, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); /*no break*/ @@ -756,6 +755,7 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t ms_warning("Receiving reINVITE or UPDATE while in state [%s], should not happen.",linphone_call_state_to_string(call->state)); break; } + sal_error_info_reset(&sei); } /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ @@ -763,7 +763,7 @@ static void call_updating(SalOp *op, bool_t is_update){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); SalMediaDescription *rmd=sal_call_get_remote_media_description(op); - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (!call) { ms_error("call_updating(): call doesn't exist anymore"); @@ -794,18 +794,18 @@ static void call_updating(SalOp *op, bool_t is_update){ md=sal_call_get_final_media_description(call->op); if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); + sal_error_info_reset(&sei); return; } if (is_update && prev_result_desc && md){ int diff=sal_media_description_equals(prev_result_desc,md); if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){ ms_warning("Cannot accept this update, it is changing parameters that require user approval"); - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonUnknown, "SIP", 504, "Cannot change the session parameters without prompting the user", NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); + sal_error_info_reset(&sei); return; } } diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 4883a0d5f..ffe29fed7 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -59,9 +59,6 @@ void linphone_error_info_unref ( LinphoneErrorInfo* ei ) { belle_sip_object_unref(ei); } -void linphone_error_info_set_reason ( LinphoneErrorInfo* ei, LinphoneReason reason ) { - ei->reason = reason; -} const char *linphone_reason_to_string(LinphoneReason err){ switch(err) { @@ -215,29 +212,30 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){ } } -LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei){ - - return ei->sub_ei; +void linphone_error_info_fields_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + sei->reason = linphone_reason_to_sal(linphone_error_info_get_reason(ei)); + sei->status_string = bctbx_strdup(ei->phrase); + sei->full_string = bctbx_strdup(ei->full_string); + sei->warnings = bctbx_strdup(ei->warnings); + sei->protocol_code = ei->protocol_code; + sei->protocol = bctbx_strdup(ei->protocol); } - -void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ - if (appended_ei != NULL){ - ei->sub_ei = linphone_error_info_ref(appended_ei); + +void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + + linphone_error_info_fields_to_sal(ei, sei); + if (ei->sub_ei !=NULL) { + + linphone_error_info_to_sal(ei->sub_ei, sei->sub_sei); } } + void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning){ linphone_error_info_reset(ei); ei->reason = reason; ei->protocol_code = code; - if (protocol != NULL){ - ei->protocol = bctbx_strdup(protocol); - } - else{ - const char* prot = "SIP"; - ei->protocol = bctbx_strdup(prot); - } - + ei->protocol = bctbx_strdup(protocol ? protocol : "SIP"); ei->phrase = bctbx_strdup(status_string); ei->warnings = bctbx_strdup(warning); } @@ -268,6 +266,36 @@ int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei) { return ei->protocol_code; } -const LinphoneErrorInfo * linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei){ +LinphoneErrorInfo * linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei){ return ei->sub_ei; } + +void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason){ + ei->reason = reason; +} + +void linphone_error_info_set_protocol(LinphoneErrorInfo *ei, const char *proto){ + STRING_SET(ei->protocol, proto); +} + +void linphone_error_info_set_protocol_code(LinphoneErrorInfo *ei, int code){ + ei->protocol_code = code; +} + +void linphone_error_info_set_phrase(LinphoneErrorInfo *ei, const char *phrase){ + STRING_SET(ei->phrase, phrase); +} + +void linphone_error_info_set_warnings(LinphoneErrorInfo *ei, const char *warnings){ + STRING_SET(ei->warnings, warnings); +} + +void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ + if (appended_ei != NULL){ + linphone_error_info_ref(appended_ei); + } + if (ei->sub_ei){ + linphone_error_info_unref(ei->sub_ei); + } + ei->sub_ei = appended_ei; +} diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 4760aee76..683e8286f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5157,29 +5157,9 @@ int linphone_call_terminate(LinphoneCall *call) { return 0; } -static void linphone_error_info_fields_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ - - sei->reason = linphone_error_info_get_reason(ei); - sei->status_string = bctbx_strdup(ei->phrase); - sei->full_string = bctbx_strdup(ei->full_string); - sei->warnings = bctbx_strdup(ei->warnings); - sei->protocol_code = ei->protocol_code; - sei->protocol = bctbx_strdup(ei->protocol); - -} - -static void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ - - linphone_error_info_fields_to_sal(ei, sei); - if (ei->sub_ei !=NULL) { - - linphone_error_info_to_sal(ei->sub_ei, sei->sub_sei); - } -} int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei){ - SalErrorInfo sei ; - sal_error_info_init_to_null(&sei); + SalErrorInfo sei={0}; LinphoneErrorInfo* p_ei = (LinphoneErrorInfo*) ei; ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); @@ -5220,7 +5200,7 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { char *real_url = NULL; LinphoneCore *lc; LinphoneAddress *real_parsed_url; - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (call->state != LinphoneCallIncomingReceived) { ms_error("Bad state for call redirection."); @@ -5236,7 +5216,6 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { } real_url = linphone_address_as_string(real_parsed_url); - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei, real_url); ms_free(real_url); @@ -5244,6 +5223,7 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { call->non_op_error = TRUE; terminate_call(call); linphone_address_unref(real_parsed_url); + sal_error_info_reset(&sei); return 0; } @@ -5259,10 +5239,9 @@ int linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { int linphone_call_decline_with_error_info(LinphoneCall * call, const LinphoneErrorInfo *ei) { - SalErrorInfo sei; - sal_error_info_init_to_null(&sei); - SalErrorInfo sub_sei; - sal_error_info_init_to_null(&sub_sei); + SalErrorInfo sei = {0}; + SalErrorInfo sub_sei = {0}; + sei.sub_sei = &sub_sei; if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { @@ -5869,7 +5848,7 @@ void linphone_call_reinvite_to_recover_from_connection_loss(LinphoneCall *call) } void linphone_call_repair_if_broken(LinphoneCall *call){ - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (!call->broken) return; if (!call->core->media_network_reachable) return; @@ -5899,7 +5878,6 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ break; case LinphoneCallUpdatedByRemote: if (sal_call_dialog_request_pending(call->op)) { - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei, SalReasonServiceUnavailable,"SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); } @@ -5923,6 +5901,7 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ call->broken = FALSE; break; } + sal_error_info_reset(&sei); } void linphone_call_refresh_sockets(LinphoneCall *call){ diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 99141e869..672e5690a 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -216,6 +216,10 @@ extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setLogCollectionP ReleaseStringUTFChars(env, jpath, path); } +extern "C" jlong Java_org_linphone_core_LinphoneCoreFactoryImpl_createErrorInfoNative(JNIEnv* env, jobject thiz){ + return (jlong)linphone_factory_create_error_info(linphone_factory_get()); +} + extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreFactoryImpl_getAllDialPlanNative(JNIEnv *env, jobject thiz) { LinphoneDialPlan *countries; jclass addr_class = env->FindClass("org/linphone/core/DialPlanImpl"); @@ -3691,6 +3695,18 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_mediaInProgress( JNI return (jboolean) linphone_call_media_in_progress((LinphoneCall*)ptr); } +extern "C" void Java_org_linphone_core_LinphoneCallImpl_declineWithErrorInfo( JNIEnv* env + ,jobject thiz + ,jlong callptr, jlong eiptr) { + linphone_call_decline_with_error_info((LinphoneCall*)callptr, (LinphoneErrorInfo*)eiptr); +} + +extern "C" void Java_org_linphone_core_LinphoneCallImpl_terminateWithErrorInfo( JNIEnv* env + ,jobject thiz + ,jlong callptr, jlong eiptr) { + linphone_call_terminate_with_error_info((LinphoneCall*)callptr, (LinphoneErrorInfo*)eiptr); +} + //LinphoneFriend extern "C" jlong Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env ,jobject thiz @@ -7317,6 +7333,86 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getPhrase(JNIEnv return tmp ? env->NewStringUTF(tmp) : NULL; } +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: getProtocol + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getProtocol(JNIEnv *env, jobject jobj, jlong ei){ + const char *tmp=linphone_error_info_get_protocol((const LinphoneErrorInfo*)ei); + return tmp ? env->NewStringUTF(tmp) : NULL; +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: getSubErrorInfo + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_linphone_core_ErrorInfoImpl_getSubErrorInfo(JNIEnv *env, jobject jobj, jlong ei){ + return (jlong)linphone_error_info_get_sub_error_info((LinphoneErrorInfo*)ei); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setReason + * Signature: (JI) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setReason(JNIEnv *env, jobject jobj, jlong ei, jint reason){ + linphone_error_info_set_reason((LinphoneErrorInfo*)ei, (LinphoneReason)reason); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: getProtocolCode + * Signature: (JI) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setProtocolCode(JNIEnv *env, jobject jobj, jlong ei, jint code){ + return linphone_error_info_set_protocol_code((LinphoneErrorInfo*)ei, code); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setPhrase + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setPhrase(JNIEnv *env, jobject jobj, jlong ei, jstring phrase){ + const char *tmp = GetStringUTFChars(env,phrase); + linphone_error_info_set_phrase((LinphoneErrorInfo*)ei, tmp); + if (phrase) ReleaseStringUTFChars(env, phrase, tmp); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setProtocol + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setProtocol(JNIEnv *env, jobject jobj, jlong ei, jstring protocol){ + const char *tmp = GetStringUTFChars(env, protocol); + linphone_error_info_set_protocol((LinphoneErrorInfo*)ei, tmp); + if (protocol) ReleaseStringUTFChars(env, protocol, tmp); +} + + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setWarnings + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setWarnings(JNIEnv *env, jobject jobj, jlong ei, jstring warnings){ + const char *tmp = GetStringUTFChars(env, warnings); + linphone_error_info_set_warnings((LinphoneErrorInfo*)ei, tmp); + if (warnings) ReleaseStringUTFChars(env, warnings, tmp); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setSubErrorInfo + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setSubErrorInfo(JNIEnv *env, jobject jobj, jlong ei, jlong sub_ei){ + linphone_error_info_set_sub_error_info((LinphoneErrorInfo*)ei, (LinphoneErrorInfo*)sub_ei); +} + /* * Class: org_linphone_core_ErrorInfoImpl * Method: getDetails diff --git a/coreapi/private.h b/coreapi/private.h index 036a44203..8688e5cf0 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1296,6 +1296,7 @@ LinphoneContent * linphone_content_copy(const LinphoneContent *ref); SalBodyHandler *sal_body_handler_from_content(const LinphoneContent *content); SalReason linphone_reason_to_sal(LinphoneReason reason); LinphoneReason linphone_reason_from_sal(SalReason reason); +void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei); LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires); LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name); void linphone_event_unpublish(LinphoneEvent *lev); diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 025a18e66..121983924 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -63,11 +63,12 @@ LINPHONE_PUBLIC void linphone_error_info_unref(LinphoneErrorInfo *ei); LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei); /** - * Get pointer to chained LinphoneErrorInfo set in sub_ei. + * Get pointer to chained LinphoneErrorInfo set in sub_ei. + * It corresponds to a Reason header in a received SIP response. * @param ei ErrorInfo object * @return LinphoneErrorInfo pointer defined in the ei object. */ -LINPHONE_PUBLIC LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei); +LINPHONE_PUBLIC LinphoneErrorInfo* linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei); /** * Get textual phrase from the error info. @@ -113,19 +114,48 @@ LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, const char * /** * Set the sub_ei in LinphoneErrorInfo to another LinphoneErrorInfo. - * Used when there is more than one reason header. + * Used when a reason header is to be added in a SIP response. The first level LinphoneErrorInfo defines the SIP response code and phrase, + * the second (sub) LinphoneErroInfo defining the content of the Reason header. * @param[in] ei LinphoneErrorInfo object to which the other LinphoneErrorInfo will be appended as ei->sub_ei. * @param[in] appended_ei LinphoneErrorInfo to append */ LINPHONE_PUBLIC void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei); /** - * Assign reason LinphoneReason to a LinphoneErrorUnfo object. + * Assign reason LinphoneReason to a LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] reason reason from LinphoneReason enum */ LINPHONE_PUBLIC void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason); +/** + * Assign protocol name to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] proto the protocol name + */ +LINPHONE_PUBLIC void linphone_error_info_set_protocol(LinphoneErrorInfo *ei, const char *proto); + +/** + * Assign protocol code to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] code the protocol code + */ +LINPHONE_PUBLIC void linphone_error_info_set_protocol_code(LinphoneErrorInfo *ei, int code); + +/** + * Assign phrase to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] phrase the phrase explaining the error + */ +LINPHONE_PUBLIC void linphone_error_info_set_phrase(LinphoneErrorInfo *ei, const char *phrase); + +/** + * Assign warnings to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] phrase the warnings + */ +LINPHONE_PUBLIC void linphone_error_info_set_warnings(LinphoneErrorInfo *ei, const char *warnings); + /** * @} */ diff --git a/java/common/org/linphone/core/ErrorInfo.java b/java/common/org/linphone/core/ErrorInfo.java index 348f7fd61..6c4e76dc6 100644 --- a/java/common/org/linphone/core/ErrorInfo.java +++ b/java/common/org/linphone/core/ErrorInfo.java @@ -6,6 +6,10 @@ public interface ErrorInfo { * @return the reason. */ Reason getReason(); + /** + * Get the protocol name for which the error code (returned by getProtocolCode()) is meaningful. + **/ + String getProtocol(); /** * Get the protocol code corresponding to the error (typically a SIP status code). * @return the code. @@ -16,9 +20,46 @@ public interface ErrorInfo { * @return the reason phrase. */ String getPhrase(); + /** + * Get content of warning header, if any. + **/ + String getWarnings(); + /** + * Get additional error information, which is provided as a Reason header in SIP response. + **/ + ErrorInfo getSubErrorInfo(); + + /** + * Set Reason enum. + */ + void setReason(Reason r); + /** + * Set the protocol name for which the error code (set by setProtocolCode()) is meaningful. + **/ + void setProtocol(String protocol); + /** + * Set the protocol code corresponding to the error (typically a SIP status code). + * @return the code. + */ + void setProtocolCode(int code); + /** + * Set the reason-phrase provided by the protocol (typically a SIP reason-phrase). + * @return the reason phrase. + */ + void setPhrase(String phrase); + /** + * Set warnings. + **/ + void setWarnings(String warnings); + /** + * Set additional error information, which is provided as a Reason header in SIP response. + **/ + void setSubErrorInfo(ErrorInfo sub_ei); + /** * Get details about the error, if provided by the protocol. For SIP it consists of the content of a Warning or Reason header. * @return details about the error. + * @deprecated */ String getDetails(); } diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index b2342a410..8cb43e796 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -391,13 +391,13 @@ public interface LinphoneCall { * Call player enable to stream a media file through a call * @return A player */ - public LinphonePlayer getPlayer(); + LinphonePlayer getPlayer(); /** * Create a new chat room for messaging from a call if not already existing, else return existing one * @return LinphoneChatRoom where messaging can take place. */ - public LinphoneChatRoom getChatRoom() ; + LinphoneChatRoom getChatRoom() ; /** * Set the callbacks associated with the LinphoneCall. @@ -409,4 +409,15 @@ public interface LinphoneCall { * This is an indication - the application remains responsible for answering the call. **/ boolean askedToAutoAnswer(); + + /** + * Decline a pending incoming call providing an ErrorInfo object. + **/ + void declineWithErrorInfo(ErrorInfo ei); + + /** + * Terminate a call providing an ErrorInfo object. + **/ + void terminateWithErrorInfo(ErrorInfo ei); } + diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index 5bd3cfe52..98e8e1e0d 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -188,6 +188,11 @@ abstract public class LinphoneCoreFactory { * Create LinphoneAccountCreator object */ abstract public LinphoneAccountCreator createAccountCreator(LinphoneCore lc, String url); + + /** + * Create ErrorInfo object + */ + abstract public ErrorInfo createErrorInfo(); /** * Array of countries list diff --git a/java/impl/org/linphone/core/ErrorInfoImpl.java b/java/impl/org/linphone/core/ErrorInfoImpl.java index e9b6bd5f3..f49bfdcfb 100644 --- a/java/impl/org/linphone/core/ErrorInfoImpl.java +++ b/java/impl/org/linphone/core/ErrorInfoImpl.java @@ -1,41 +1,102 @@ package org.linphone.core; public class ErrorInfoImpl implements ErrorInfo { - private Reason mReason; - private int mCode; - private String mPhrase; - private String mDetails; + protected long mNativePtr; + + private native void ref(long nativePtr); + private native void unref(long nativePtr); private native int getReason(long nativePtr); + private native String getProtocol(long nativePtr); private native int getProtocolCode(long nativePtr); private native String getPhrase(long nativePtr); - private native String getDetails(long nativePtr); + private native String getWarnings(long nativePtr); + private native long getSubErrorInfo(long nativePtr); + + private native void setReason(long nativePtr, int reason); + private native void setProtocol(long nativePtr, String proto); + private native void setProtocolCode(long nativePtr, int code); + private native void setPhrase(long nativePtr, String phrase); + private native void setWarnings(long nativePtr, String warnings); + private native void setSubErrorInfo(long nativePtr, long other_nativePtr); + + public ErrorInfoImpl(long nativePtr, boolean ownsRef){ + if (!ownsRef) ref(nativePtr); + mNativePtr = nativePtr; + } public ErrorInfoImpl(long nativePtr){ - mReason=Reason.fromInt(getReason(nativePtr)); - mCode=getProtocolCode(nativePtr); - mPhrase=getPhrase(nativePtr); - mDetails=getDetails(nativePtr); + ref(nativePtr); + mNativePtr = nativePtr; } @Override public Reason getReason() { - return mReason; + return Reason.fromInt(getReason(mNativePtr)); + } + + @Override + public String getProtocol() { + return getProtocol(mNativePtr); } @Override public int getProtocolCode() { - return mCode; + return getProtocolCode(mNativePtr); } @Override public String getPhrase() { - return mPhrase; + return getPhrase(mNativePtr); + } + + @Override + public String getWarnings(){ + return getWarnings(mNativePtr); + } + + @Override + public ErrorInfo getSubErrorInfo(){ + long sub_ei = getSubErrorInfo(mNativePtr); + return sub_ei != 0 ? new ErrorInfoImpl(sub_ei, false) : null; + } + + + @Override + public void setReason(Reason reason) { + setReason(mNativePtr, reason.mValue); + } + + @Override + public void setProtocol(String proto) { + setProtocol(mNativePtr, proto); } @Override - public String getDetails() { - return mDetails; + public void setProtocolCode(int code) { + setProtocolCode(mNativePtr, code); } + @Override + public void setPhrase(String phrase) { + setPhrase(mNativePtr, phrase); + } + + @Override + public void setWarnings(String warnings){ + setWarnings(mNativePtr, warnings); + } + + @Override + public void setSubErrorInfo(ErrorInfo ei){ + setSubErrorInfo(mNativePtr, ei != null ? ((ErrorInfoImpl)ei).mNativePtr : 0); + } + + + @Override + public String getDetails() { + return getWarnings(); + } + + } diff --git a/java/impl/org/linphone/core/LinphoneCallImpl.java b/java/impl/org/linphone/core/LinphoneCallImpl.java index c276ce07d..f1338c423 100644 --- a/java/impl/org/linphone/core/LinphoneCallImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallImpl.java @@ -93,20 +93,26 @@ class LinphoneCallImpl implements LinphoneCall { return LinphoneCall.State.fromInt(getState(nativePtr)); } public LinphoneCallParams getCurrentParams() { - return new LinphoneCallParamsImpl(getCurrentParams(nativePtr)); + synchronized(mCore){ + return new LinphoneCallParamsImpl(getCurrentParams(nativePtr)); + } } public LinphoneCallParams getCurrentParamsCopy(){ return getCurrentParams(); } public LinphoneCallParams getRemoteParams() { - long remoteParamsPtr = getRemoteParams(nativePtr); - if (remoteParamsPtr == 0) { - return null; + synchronized(mCore){ + long remoteParamsPtr = getRemoteParams(nativePtr); + if (remoteParamsPtr == 0) { + return null; + } + return new LinphoneCallParamsImpl(remoteParamsPtr); } - return new LinphoneCallParamsImpl(remoteParamsPtr); } public void enableCamera(boolean enabled) { - enableCamera(nativePtr, enabled); + synchronized(mCore){ + enableCamera(nativePtr, enabled); + } } public boolean cameraEnabled() { return cameraEnabled(nativePtr); @@ -200,7 +206,9 @@ class LinphoneCallImpl implements LinphoneCall { private native void takeSnapshot(long nativePtr, String path); public void takeSnapshot(String path) { - takeSnapshot(nativePtr, path); + synchronized(mCore){ + takeSnapshot(nativePtr, path); + } } private native void zoomVideo(long nativePtr, float factor, float cx, float cy); @@ -211,12 +219,16 @@ class LinphoneCallImpl implements LinphoneCall { private native void startRecording(long nativePtr); @Override public void startRecording() { - startRecording(nativePtr); + synchronized(mCore){ + startRecording(nativePtr); + } } private native void stopRecording(long nativePtr); @Override public void stopRecording() { - stopRecording(nativePtr); + synchronized(mCore){ + stopRecording(nativePtr); + } } private native int getTransferState(long nativePtr); @Override @@ -226,7 +238,9 @@ class LinphoneCallImpl implements LinphoneCall { private native int sendInfoMessage(long callPtr, long msgptr); @Override public void sendInfoMessage(LinphoneInfoMessage msg) { - sendInfoMessage(nativePtr,((LinphoneInfoMessageImpl)msg).nativePtr); + synchronized(mCore){ + sendInfoMessage(nativePtr,((LinphoneInfoMessageImpl)msg).nativePtr); + } } private native Object getTransfererCall(long callPtr); @Override @@ -246,7 +260,9 @@ class LinphoneCallImpl implements LinphoneCall { private native long getErrorInfo(long nativePtr); @Override public ErrorInfo getErrorInfo() { - return new ErrorInfoImpl(getErrorInfo(nativePtr)); + synchronized(mCore){ + return new ErrorInfoImpl(getErrorInfo(nativePtr)); + } } @Override public void setUserData(Object obj) { @@ -260,18 +276,24 @@ class LinphoneCallImpl implements LinphoneCall { private native long getPlayer(long callPtr); @Override public LinphonePlayer getPlayer() { - return new LinphonePlayerImpl(getPlayer(nativePtr)); + synchronized(mCore){ + return new LinphonePlayerImpl(getPlayer(nativePtr)); + } } private native Object getChatRoom(long nativePtr); @Override public LinphoneChatRoom getChatRoom() { - return (LinphoneChatRoom)(getChatRoom(nativePtr)); + synchronized(mCore){ + return (LinphoneChatRoom)(getChatRoom(nativePtr)); + } } @Override public void setListener(LinphoneCallListener listener) { - setListener(nativePtr, listener); + synchronized(mCore){ + setListener(nativePtr, listener); + } } public LinphoneAddress getDiversionAddress() { @@ -288,5 +310,20 @@ class LinphoneCallImpl implements LinphoneCall { public boolean askedToAutoAnswer(){ return askedToAutoAnswer(nativePtr); } + + private native void declineWithErrorInfo(long call, long ei); + @Override + public void declineWithErrorInfo(ErrorInfo ei){ + synchronized(mCore){ + declineWithErrorInfo(nativePtr, ((ErrorInfoImpl)ei).mNativePtr); + } + } + private native void terminateWithErrorInfo(long call, long ei); + @Override + public void terminateWithErrorInfo(ErrorInfo ei){ + synchronized(mCore){ + terminateWithErrorInfo(nativePtr, ((ErrorInfoImpl)ei).mNativePtr); + } + } } diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index d1f7f2952..1c817de3c 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -255,4 +255,10 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { public DialPlan[] getAllDialPlan(){ return getAllDialPlanNative(); } + + private native long createErrorInfoNative(); + @Override + public ErrorInfo createErrorInfo(){ + return new ErrorInfoImpl(createErrorInfoNative(), true); + } } diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index c2cb29b7e..91848203b 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1221,7 +1221,7 @@ static void call_declined_with_error(void) { BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); rcvd_ei = linphone_call_get_error_info(out_call); - sub_rcvd_ei = linphone_error_info_get_sub(rcvd_ei); + sub_rcvd_ei = linphone_error_info_get_sub_error_info(rcvd_ei); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rcvd_ei), "Decline"); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rcvd_ei), "SIP"); @@ -1745,7 +1745,7 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) { result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000) && wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); - + BC_ASSERT_TRUE(result); caller_params = linphone_core_create_call_params(caller_mgr->lc, call_caller); @@ -1870,6 +1870,8 @@ static void call_callee_with_custom_header_or_sdp_attributes(void) { && wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); + BC_ASSERT_TRUE(result); + caller_remote_params = linphone_call_get_remote_params(call_caller); value = linphone_call_params_get_custom_sdp_attribute(caller_remote_params, "working"); BC_ASSERT_PTR_NOT_NULL(value);