Commit 95098f05 authored by Simon Morlat's avatar Simon Morlat

Make LinphoneErrorInfo a belle-sip object. Add new accessors, and make it able...

Make LinphoneErrorInfo a belle-sip object. Add new accessors, and make it able to take Reason headers in incoming requests (feature to be tested)
parent 67c8f846
......@@ -87,6 +87,7 @@ struct SalOp{
SalOpBase base;
const belle_sip_listener_callbacks_t *callbacks;
SalErrorInfo error_info;
SalErrorInfo reason_error_info;
belle_sip_client_transaction_t *pending_auth_transaction;
belle_sip_server_transaction_t* pending_server_trans;
belle_sip_server_transaction_t* pending_update_server_trans;
......
......@@ -150,7 +150,7 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event
if (op->pending_client_trans && (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_INIT)) {
sal_error_info_set(&op->error_info, SalReasonIOError, 503, "IO error", NULL);
sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "IO error", NULL);
op->base.root->callbacks.call_failure(op);
if (!op->dialog || belle_sip_dialog_get_state(op->dialog) != BELLE_SIP_DIALOG_CONFIRMED){
......@@ -386,7 +386,7 @@ static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t
if (!op->dialog) {
/*call terminated very early*/
sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
sal_error_info_set(&op->error_info, SalReasonRequestTimeout, "SIP", 408, "Request timeout", NULL);
op->base.root->callbacks.call_failure(op);
op->state = SalOpStateTerminating;
call_set_released(op);
......@@ -421,7 +421,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
release_call=TRUE;
}else if (op->state == SalOpStateEarly && code < 200){
/*call terminated early*/
sal_error_info_set(&op->error_info,SalReasonIOError,503,"I/O error",NULL);
sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "I/O error", NULL);
op->state = SalOpStateTerminating;
op->base.root->callbacks.call_failure(op);
release_call=TRUE;
......@@ -1004,9 +1004,9 @@ int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){
}
/*it failed why ?*/
if (belle_sip_dialog_request_pending(op->dialog))
sal_error_info_set(&op->error_info,SalReasonRequestPending,491,NULL,NULL);
sal_error_info_set(&op->error_info,SalReasonRequestPending, "SIP", 491,NULL,NULL);
else
sal_error_info_set(&op->error_info,SalReasonUnknown,500,NULL,NULL);
sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", 500,NULL,NULL);
return -1;
}
......
......@@ -52,7 +52,7 @@ static void subscribe_refresher_listener (belle_sip_refresher_t* refresher
if (status_code == 503) { /*refresher returns 503 for IO error*/
reason = SalReasonIOError;
}
sal_error_info_set(&op->error_info,reason,status_code,reason_phrase,NULL);
sal_error_info_set(&op->error_info, reason, "SIP", status_code,reason_phrase,NULL);
op->base.root->callbacks.subscribe_response(op,sss, will_retry);
}else if (status_code==0){
op->base.root->callbacks.on_expire(op);
......@@ -72,7 +72,7 @@ static void subscribe_process_io_error(void *user_ctx, const belle_sip_io_error_
/*this is handling outgoing out-of-dialog notifies*/
if (strcmp(method,"NOTIFY")==0){
SalErrorInfo *ei=&op->error_info;
sal_error_info_set(ei,SalReasonIOError,0,NULL,NULL);
sal_error_info_set(ei,SalReasonIOError, "SIP", 0,NULL,NULL);
op->base.root->callbacks.on_notify_response(op);
}
}
......@@ -131,7 +131,7 @@ static void subscribe_process_timeout(void *user_ctx, const belle_sip_timeout_ev
/*this is handling outgoing out-of-dialog notifies*/
if (strcmp(method,"NOTIFY")==0){
SalErrorInfo *ei=&op->error_info;
sal_error_info_set(ei,SalReasonRequestTimeout,0,NULL,NULL);
sal_error_info_set(ei,SalReasonRequestTimeout, "SIP", 0,NULL,NULL);
op->base.root->callbacks.on_notify_response(op);
}
}
......
......@@ -580,17 +580,22 @@ void sal_error_info_reset(SalErrorInfo *ei){
ms_free(ei->full_string);
ei->full_string=NULL;
}
if (ei->protocol){
ms_free(ei->protocol);
ei->protocol = NULL;
}
ei->protocol_code=0;
ei->reason=SalReasonNone;
}
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning){
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol, int code, const char *status_string, const char *warning){
sal_error_info_reset(ei);
if (reason==SalReasonUnknown) ei->reason=_sal_reason_from_sip_code(code);
if (reason==SalReasonUnknown && strcmp(protocol, "SIP") == 0) ei->reason=_sal_reason_from_sip_code(code);
else ei->reason=reason;
ei->protocol_code=code;
ei->status_string=status_string ? ms_strdup(status_string) : NULL;
ei->warnings=warning ? ms_strdup(warning) : NULL;
ei->protocol = protocol ? ms_strdup(protocol) : NULL;
if (ei->status_string){
if (ei->warnings)
ei->full_string=ms_strdup_printf("%s %s",ei->status_string,ei->warnings);
......@@ -598,24 +603,36 @@ void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char
}
}
void sal_op_set_reason_error_info(SalOp *op, belle_sip_message_t *msg){
belle_sip_header_reason_t* reason_header = belle_sip_message_get_header_by_type(msg,belle_sip_header_reason_t);
if (reason_header){
SalErrorInfo *ei=&op->reason_error_info;
const char *protocol = belle_sip_header_reason_get_protocol(reason_header);
int code = belle_sip_header_reason_get_cause(reason_header);
const char *text = belle_sip_header_reason_get_text(reason_header);
sal_error_info_set(ei, SalReasonUnknown, protocol, code, text, NULL);
}
}
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response){
int code = belle_sip_response_get_status_code(response);
const char *reason_phrase=belle_sip_response_get_reason_phrase(response);
/*Remark: the reason header is to be used mainly in SIP requests, thus the use and prototype of this function should be changed.*/
belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
belle_sip_header_t *warning=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Warning");
SalErrorInfo *ei=&op->error_info;
const char *warnings;
warnings=warning ? belle_sip_header_get_unparsed_value(warning) : NULL;
if (warnings==NULL) warnings=reason_header ? belle_sip_header_get_unparsed_value(reason_header) : NULL;
sal_error_info_set(ei,SalReasonUnknown,code,reason_phrase,warnings);
sal_error_info_set(ei,SalReasonUnknown,"SIP", code,reason_phrase,warnings);
}
const SalErrorInfo *sal_op_get_error_info(const SalOp *op){
return &op->error_info;
}
const SalErrorInfo * sal_op_get_reason_error_info(const SalOp *op){
return &op->reason_error_info;
}
static void unlink_op_with_dialog(SalOp *op, belle_sip_dialog_t* dialog){
belle_sip_dialog_set_application_data(dialog,NULL);
sal_op_unref(op);
......
......@@ -34,12 +34,12 @@ static void process_error( SalOp* op) {
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
SalOp* op = (SalOp*)user_ctx;
sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO Error",NULL);
sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL);
process_error(op);
}
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
SalOp* op=(SalOp*)user_ctx;
sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL);
process_error(op);
}
......
......@@ -36,7 +36,7 @@ static void publish_refresher_listener (belle_sip_refresher_t* refresher
sip_etag_string = belle_sip_header_get_unparsed_value(sip_etag);
}
sal_op_set_entity_tag(op, sip_etag_string);
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", status_code,reason_phrase,NULL);
sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
op->base.root->callbacks.on_publish_response(op);
}
......
......@@ -32,7 +32,7 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
/*only take first one for now*/
op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data));
}
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", status_code,reason_phrase,NULL);
if (status_code>=200){
sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
}
......
......@@ -818,7 +818,8 @@ static void call_terminated(SalOp *op, const char *from){
break;
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
sal_error_info_set(&call->non_op_error,SalReasonRequestTimeout,0,"Incoming call cancelled",NULL);
linphone_error_info_set(call->ei, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL);
call->non_op_error = TRUE;
break;
default:
break;
......
......@@ -463,7 +463,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
}
if (retval > 0) {
sal_error_info_set((SalErrorInfo *)sal_op_get_error_info(op), SalReasonNotAcceptable, retval, "Unable to encrypt IM", NULL);
sal_error_info_set((SalErrorInfo *)sal_op_get_error_info(op), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", NULL);
store_or_update_chat_message(msg);
linphone_chat_message_update_state(msg, LinphoneChatMessageStateNotDelivered);
linphone_chat_message_unref(msg);
......@@ -1656,6 +1656,8 @@ void linphone_chat_message_destroy(LinphoneChatMessage *msg) {
static void _linphone_chat_message_destroy(LinphoneChatMessage *msg) {
if (msg->op)
sal_op_release(msg->op);
if (msg->ei)
linphone_error_info_unref(msg->ei);
if (msg->message)
ms_free(msg->message);
if (msg->external_body_url)
......@@ -1706,7 +1708,9 @@ static void linphone_chat_message_release(LinphoneChatMessage *msg) {
}
const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg) {
return linphone_error_info_from_sal_op(msg->op);
if (!msg->ei) ((LinphoneChatMessage*)msg)->ei = linphone_error_info_new(); /*let's do it mutable*/
linphone_error_info_from_sal_op(msg->ei, msg->op);
return msg->ei;
}
LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) {
......
......@@ -20,6 +20,49 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "linphone/core.h"
#include "private.h"
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneErrorInfo);
#define STRING_RESET(field) if (field) ms_free(field); field = NULL;
static void error_info_destroy(LinphoneErrorInfo *ei){
if (ei->protocol) ms_free(ei->protocol);
if (ei->phrase) ms_free(ei->phrase);
if (ei->warnings) ms_free(ei->phrase);
if (ei->full_string) ms_free(ei->full_string);
}
static void error_info_clone(LinphoneErrorInfo *ei, const LinphoneErrorInfo *other){
ei->protocol = ms_strdup_safe(other->protocol);
ei->phrase = ms_strdup_safe(other->phrase);
ei->warnings = ms_strdup_safe(other->phrase);
ei->full_string = ms_strdup_safe(other->full_string);
}
BELLE_SIP_INSTANCIATE_VPTR(LinphoneErrorInfo, belle_sip_object_t,
error_info_destroy, // destroy
error_info_clone, // clone
NULL, // Marshall
FALSE
);
LinphoneErrorInfo *linphone_error_info_new(void){
LinphoneErrorInfo *ei = belle_sip_object_new(LinphoneErrorInfo);
return ei;
}
LinphoneErrorInfo* linphone_error_info_ref ( LinphoneErrorInfo* ei ) {
return (LinphoneErrorInfo*) belle_sip_object_ref(ei);
}
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) {
......@@ -112,23 +155,101 @@ int linphone_reason_to_error_code(LinphoneReason reason) {
return 400;
}
void linphone_error_info_reset(LinphoneErrorInfo *ei){
ei->reason = LinphoneReasonNone;
STRING_RESET(ei->protocol);
STRING_RESET(ei->phrase);
STRING_RESET(ei->full_string);
STRING_RESET(ei->warnings);
ei->protocol_code = 0;
if (ei->sub_ei) {
linphone_error_info_unref(ei->sub_ei);
ei->sub_ei = NULL;
}
}
void linphone_error_info_from_sal(LinphoneErrorInfo *ei, const SalErrorInfo *sei){
ei->reason = linphone_reason_from_sal(sei->reason);
ei->phrase = ms_strdup_safe(sei->status_string);
ei->full_string = ms_strdup_safe(sei->full_string);
ei->warnings = ms_strdup_safe(sei->warnings);
ei->protocol_code = sei->protocol_code;
ei->protocol = ms_strdup_safe(sei->protocol);
}
/* If a reason header is provided (in reason_ei), then create a sub LinphoneErrorInfo attached to the first one, unless the reason header
is in the request, in which case no primary error is given.*/
void linphone_error_info_from_sal_reason_ei(LinphoneErrorInfo *ei, const SalErrorInfo *reason_ei){
if (ei->reason == LinphoneReasonNone){
/*no primary error given*/
linphone_error_info_reset(ei);
linphone_error_info_from_sal(ei, reason_ei);
return;
}
if (ei->sub_ei){
if (reason_ei->reason == SalReasonNone){
linphone_error_info_unref(ei->sub_ei);
ei->sub_ei = NULL;
}
}else{
if (reason_ei->reason != SalReasonNone){
ei->sub_ei = linphone_error_info_new();
}
}
if (reason_ei->reason != SalReasonNone){
linphone_error_info_from_sal(ei->sub_ei, reason_ei);
}
}
void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){
if (op==NULL) {
/*leave previous values in LinphoneErrorInfo, the op may have been released already.*/
return;
}else{
const SalErrorInfo *sei;
linphone_error_info_reset(ei);
sei = sal_op_get_error_info(op);
linphone_error_info_from_sal(ei, sei);
sei = sal_op_get_reason_error_info(op);
linphone_error_info_from_sal_reason_ei(ei, sei);
}
}
void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int code, const char *status_string, const char *warning){
linphone_error_info_reset(ei);
ei->reason = reason;
ei->protocol_code = code;
ei->phrase = ms_strdup_safe(status_string);
ei->warnings = ms_strdup_safe(warning);
}
LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei) {
const SalErrorInfo *sei = (const SalErrorInfo *)ei;
return linphone_reason_from_sal(sei->reason);
return ei->reason;
}
const char *linphone_error_info_get_protocol(const LinphoneErrorInfo *ei){
return ei->protocol;
}
const char *linphone_error_info_get_phrase(const LinphoneErrorInfo *ei) {
const SalErrorInfo *sei = (const SalErrorInfo *)ei;
return sei->status_string;
return ei->phrase;
}
const char *linphone_error_info_get_details(const LinphoneErrorInfo *ei) {
const SalErrorInfo *sei = (const SalErrorInfo *)ei;
return sei->warnings;
/*deprecated, kept for binary compatibility*/
const char *linphone_error_info_get_details(const LinphoneErrorInfo *ei){
return linphone_error_info_get_warnings(ei);
}
const char *linphone_error_info_get_warnings(const LinphoneErrorInfo *ei) {
return ei->warnings;
}
int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei) {
const SalErrorInfo *sei = (const SalErrorInfo *)ei;
return sei->protocol_code;
return ei->protocol_code;
}
const LinphoneErrorInfo * linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei){
return ei->sub_ei;
}
......@@ -156,7 +156,9 @@ LinphonePublishState linphone_event_get_publish_state(const LinphoneEvent *lev){
}
const LinphoneErrorInfo *linphone_event_get_error_info(const LinphoneEvent *lev){
return linphone_error_info_from_sal_op(lev->op);
if (!lev->ei) ((LinphoneEvent*)lev)->ei = linphone_error_info_new();
linphone_error_info_from_sal_op(lev->ei, lev->op);
return lev->ei;
}
LinphoneReason linphone_event_get_reason(const LinphoneEvent *lev){
......@@ -393,6 +395,7 @@ LinphoneEvent *linphone_event_ref(LinphoneEvent *lev){
}
static void linphone_event_destroy(LinphoneEvent *lev){
if (lev->ei) linphone_error_info_unref(lev->ei);
if (lev->op) sal_op_release(lev->op);
if (lev->send_custom_headers) sal_custom_header_free(lev->send_custom_headers);
ms_free(lev->name);
......
......@@ -1000,6 +1000,7 @@ static void port_config_set(LinphoneCall *call, int stream_index, int min_port,
static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
int min_port, max_port;
ms_message("New LinphoneCall [%p] initialized (LinphoneCore version: %s)",call,linphone_core_get_version());
call->ei = linphone_error_info_new();
call->core->send_call_stats_periodical_updates = lp_config_get_int(call->core->config, "misc", "send_call_stats_periodical_updates", 0);
call->main_audio_stream_index = LINPHONE_CALL_STATS_AUDIO;
call->main_video_stream_index = LINPHONE_CALL_STATS_VIDEO;
......@@ -1544,9 +1545,8 @@ static void linphone_call_free_media_resources(LinphoneCall *call){
static void linphone_call_set_released(LinphoneCall *call){
if (call->op!=NULL) {
/*transfer the last error so that it can be obtained even in Released state*/
if (call->non_op_error.reason==SalReasonNone){
const SalErrorInfo *ei=sal_op_get_error_info(call->op);
sal_error_info_set(&call->non_op_error,ei->reason,ei->protocol_code,ei->status_string,ei->warnings);
if (!call->non_op_error){
linphone_error_info_from_sal_op(call->ei, call->op);
}
/* so that we cannot have anymore upcalls for SAL
concerning this call*/
......@@ -1857,7 +1857,7 @@ static void linphone_call_destroy(LinphoneCall *obj){
}
if (obj->onhold_file) ms_free(obj->onhold_file);
sal_error_info_reset(&obj->non_op_error);
if (obj->ei) linphone_error_info_unref(obj->ei);
}
LinphoneCall * linphone_call_ref(LinphoneCall *obj){
......@@ -2046,9 +2046,10 @@ LinphoneReason linphone_call_get_reason(const LinphoneCall *call){
}
const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call){
if (call->non_op_error.reason!=SalReasonNone){
return (const LinphoneErrorInfo*)&call->non_op_error;
}else return linphone_error_info_from_sal_op(call->op);
if (!call->non_op_error){
linphone_error_info_from_sal_op(call->ei, call->op);
}
return call->ei;
}
void *linphone_call_get_user_data(const LinphoneCall *call)
......@@ -4325,7 +4326,8 @@ static void linphone_call_lost(LinphoneCall *call){
if (from) ms_free(from);
ms_message("LinphoneCall [%p]: %s", call, temp);
linphone_core_notify_display_warning(lc, temp);
sal_error_info_set(&call->non_op_error, SalReasonIOError, 503, "IO error", NULL);
call->non_op_error = TRUE;
linphone_error_info_set(call->ei, LinphoneReasonIOError, 503, "Media lost", NULL);
linphone_call_terminate(call);
linphone_core_play_named_tone(lc, LinphoneToneCallLost);
ms_free(temp);
......@@ -5029,8 +5031,10 @@ int linphone_call_resume(LinphoneCall *call) {
static void terminate_call(LinphoneCall *call) {
LinphoneCore *lc = linphone_call_get_core(call);
if ((call->state == LinphoneCallIncomingReceived) && (call->non_op_error.reason != SalReasonRequestTimeout))
call->non_op_error.reason=SalReasonDeclined;
if ((call->state == LinphoneCallIncomingReceived) && (linphone_error_info_get_reason(call->ei) != LinphoneReasonNotAnswered)){
linphone_error_info_set_reason(call->ei, LinphoneReasonDeclined);
call->non_op_error = TRUE;
}
/* Stop ringing */
linphone_core_stop_ringing(lc);
......@@ -5089,7 +5093,8 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) {
real_url = linphone_address_as_string(real_parsed_url);
sal_call_decline(call->op, SalReasonRedirect, real_url);
ms_free(real_url);
sal_error_info_set(&call->non_op_error, SalReasonRedirect, 603, "Call redirected", NULL);
linphone_error_info_set(call->ei, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL);
call->non_op_error = TRUE;
terminate_call(call);
linphone_address_unref(real_parsed_url);
return 0;
......
......@@ -2979,7 +2979,8 @@ void linphone_core_iterate(LinphoneCore *lc){
ms_message("incoming call timeout (%i)",lc->sip_conf.inc_timeout);
decline_reason = (lc->current_call != call) ? LinphoneReasonBusy : LinphoneReasonDeclined;
call->log->status=LinphoneCallMissed;
sal_error_info_set(&call->non_op_error,SalReasonRequestTimeout,408,"Not answered",NULL);
call->non_op_error = TRUE;
linphone_error_info_set(call->ei, decline_reason, linphone_reason_to_error_code(decline_reason), "Not answered", NULL);
linphone_call_decline(call, decline_reason);
}
}
......
......@@ -7278,7 +7278,7 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getPhrase(JNIEnv
* Signature: (J)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getDetails(JNIEnv *env, jobject jobj, jlong ei){
const char *tmp=linphone_error_info_get_details((const LinphoneErrorInfo*)ei);
const char *tmp=linphone_error_info_get_warnings((const LinphoneErrorInfo*)ei);
return tmp ? env->NewStringUTF(tmp) : NULL;
}
......
......@@ -124,6 +124,8 @@
#ifdef __cplusplus
extern "C" {
#endif
#define ms_strdup_safe(str) ((str) ? ms_strdup(str) : NULL)
struct _LinphoneCallParams{
belle_sip_object_t base;
......@@ -230,6 +232,7 @@ struct _LinphoneChatMessage {
belle_sip_object_t base;
LinphoneChatRoom* chat_room;
LinphoneChatMessageCbs *callbacks;
LinphoneErrorInfo *ei;
LinphoneChatMessageDir dir;
char* message;
void* message_state_changed_user_data;
......@@ -288,7 +291,7 @@ struct _LinphoneCall{
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *core;
SalErrorInfo non_op_error;
LinphoneErrorInfo *ei;
int af; /*the address family to prefer for RTP path, guessed from signaling path*/
LinphoneCallDir dir;
SalMediaDescription *biggestdesc; /*media description with all already proposed streams, used to remember the mapping of streams*/
......@@ -370,7 +373,9 @@ struct _LinphoneCall{
bool_t broken; /*set to TRUE when the call is in broken state due to network disconnection or transport */
bool_t defer_notify_incoming;
bool_t need_localip_refresh;
bool_t reinvite_on_cancel_response_requested;
bool_t non_op_error; /*set when the LinphoneErrorInfo was set at higher level than sal*/
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCall);
......@@ -624,6 +629,7 @@ struct _LinphoneProxyConfig
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *lc;
LinphoneErrorInfo *ei;
char *reg_proxy;
char *reg_identity;
LinphoneAddress* identity_address;
......@@ -1101,6 +1107,7 @@ struct _LinphoneCore
struct _LinphoneEvent{
belle_sip_object_t base;
LinphoneErrorInfo *ei;
LinphoneSubscriptionDir dir;
LinphoneCore *lc;
SalOp *op;
......@@ -1514,10 +1521,7 @@ void linphone_xml_xpath_context_init_carddav_ns(xmlparsing_context_t *xml_ctx);
char * linphone_timestamp_to_rfc3339_string(time_t timestamp);
static MS2_INLINE const LinphoneErrorInfo *linphone_error_info_from_sal_op(const SalOp *op){
if (op==NULL) return (LinphoneErrorInfo*)sal_error_info_none();
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
}
void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op);
static MS2_INLINE void payload_type_set_enable(PayloadType *pt,int value)
{
......@@ -1606,7 +1610,7 @@ BELLE_SIP_TYPE_ID(LinphonePresenceService),
BELLE_SIP_TYPE_ID(LinphonePresencePerson),
BELLE_SIP_TYPE_ID(LinphonePresenceActivity),
BELLE_SIP_TYPE_ID(LinphonePresenceNote),
BELLE_SIP_TYPE_ID(LinphoneTunnel),
BELLE_SIP_TYPE_ID(LinphoneErrorInfo)
BELLE_SIP_TYPE_ID(LinphoneConferenceParams),
BELLE_SIP_TYPE_ID(LinphoneConference),
BELLE_SIP_TYPE_ID(LinphoneInfoMessage)
......@@ -1733,6 +1737,18 @@ void linphone_call_check_ice_session(LinphoneCall *call, IceRole role, bool_t is
bool_t linphone_call_state_is_early(LinphoneCallState state);
struct _LinphoneErrorInfo{
belle_sip_object_t base;
LinphoneReason reason;
char *protocol; /* */
int protocol_code; /*from SIP response*/
char *phrase; /*from SIP response*/
char *warnings; /*from SIP response*/
char *full_string; /*concatenation of status_string + warnings*/
struct _LinphoneErrorInfo *sub_ei;
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneErrorInfo);
#ifdef __cplusplus
}
#endif
......
......@@ -225,6 +225,9 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){
if (cfg->nat_policy != NULL) {
linphone_nat_policy_unref(cfg->nat_policy);
}
if (cfg->ei){
linphone_error_info_unref(cfg->ei);
}
_linphone_proxy_config_release_ops(cfg);
}
......@@ -1334,7 +1337,9 @@ LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg) {
}
const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg){
return linphone_error_info_from_sal_op(cfg->op);
if (!cfg->ei) ((LinphoneProxyConfig*)cfg)->ei = linphone_error_info_new();
linphone_error_info_from_sal_op(cfg->ei, cfg->op);
return cfg->ei;
}
const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg) {
......
......@@ -31,6 +31,30 @@ extern "C" {
* @{
*/
/**
* Create an empty LinphoneErrorInfo object.
* The LinphoneErrorInfo object carries these fields:
* - a LinphoneReason enum member giving overall signification of the error reported.
* - the "protocol" name in which the protocol reason code has meaning, for example SIP or Q.850
* - the "protocol code", an integer referencing the kind of error reported
* - the "phrase", a text phrase describing the error
* - the "warning", the content of warning headers if any
* - a sub "LinphoneErrorInfo" may be provided if a SIP response includes a Reason header (RFC3326).
**/
LINPHONE_PUBLIC LinphoneErrorInfo *linphone_error_info_new(void);
/**
* Increment refcount.
* @param[in] ei ErrorInfo object
**/
LINPHONE_PUBLIC LinphoneErrorInfo *linphone_error_info_ref(LinphoneErrorInfo *ei);
/**
* Decrement refcount and possibly free the object.
* @param[in] ei ErrorInfo object
**/
LINPHONE_PUBLIC void linphone_error_info_unref(LinphoneErrorInfo *ei);
/**
* Get reason code from the error info.
* @param[in] ei ErrorInfo object
......@@ -48,11 +72,12 @@ LINPHONE_PUBLIC const char * linphone_error_info_get_phrase(const LinphoneErrorI
/**
* Provides additional information regarding the failure.
* With SIP protocol, the "Reason" and "Warning" headers are returned.
* With SIP protocol, the content of "Warning" headers are returned.
* @param[in] ei ErrorInfo object
* @return More details about the failure
**/
LINPHONE_PUBLIC const char * linphone_error_info_get_details(const LinphoneErrorInfo *ei);
LINPHONE_PUBLIC const char * linphone_error_info_get_warnings(const LinphoneErrorInfo *ei);
/**
* Get the status code from the low level protocol (ex a SIP status code).
......@@ -61,6 +86,14 @@ LINPHONE_PUBLIC const char * linphone_error_info_get_details(const LinphoneError
**/
LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei);
/**
* Assign information to a LinphoneErrorInfo object.
* @param[in] ei ErrorInfo object
*/
LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int code, const char *status_string, const char *warning);
LINPHONE_PUBLIC void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason);
/**
* @}
*/
......
......@@ -410,6 +410,7 @@ typedef struct SalErrorInfo{
char *status_string;
int protocol_code;
char *warnings;
char *protocol;
char *full_string; /*concatenation of status_string + warnings*/
}SalErrorInfo;
......@@ -726,8 +727,9 @@ bool_t sal_op_is_idle(SalOp *op);
const SalErrorInfo *sal_error_info_none(void);
LINPHONE_PUBLIC const SalErrorInfo *sal_op_get_error_info(const SalOp *op);
const SalErrorInfo *sal_op_get_reason_error_info(const SalOp *op);
void sal_error_info_reset(SalErrorInfo *ei);
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning);
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol, int code, const char *status_string, const char *warning);
/*entity tag used for publish (see RFC 3903)*/
const char *sal_op_get_entity_tag(const SalOp* op);
......
mediastreamer2 @ ffdd8375
Subproject commit 2377866823f41056109519fbc362ddd6fc8214e9
Subproject commit ffdd8375f332e04c0d7642fb1da414124145256e
oRTP @ 235e5175
Subproject commit 920817911d9287250d9ddf506aede06744faae4b
Subproject commit 235e5175b2befa2d3e5f19cd969b0f3bda5b9b4c
......@@ -465,7 +465,7 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const
BC_ASSERT_PTR_NOT_NULL(phrase);
if (phrase) BC_ASSERT_STRING_EQUAL(phrase,"Forbidden");
BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),403, int, "%d");
BC_ASSERT_PTR_NULL(linphone_error_info_get_details(ei));
BC_ASSERT_PTR_NULL(linphone_error_info_get_warnings(ei));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment