Merge branch 'master' into dev_loc

This commit is contained in:
Sandrine Avakian 2017-03-23 11:41:21 +01:00
commit 6adccb389b
28 changed files with 440 additions and 131 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -37,6 +37,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sqlite3.h"
#endif
typedef struct _CallLogStorageResult {
LinphoneCore *core;
bctbx_list_t *result;
} CallLogStorageResult;
/*******************************************************************************
* Internal functions *
******************************************************************************/
@ -401,6 +406,15 @@ void linphone_core_call_log_storage_close(LinphoneCore *lc) {
}
}
static LinphoneCallLog * find_call_log_by_storage_id(bctbx_list_t *call_logs, unsigned int storage_id) {
bctbx_list_t *item;
for (item = call_logs; item != NULL; item = bctbx_list_next(item)) {
LinphoneCallLog *call_log = bctbx_list_get_data(item);
if (call_log->storage_id == storage_id) return call_log;
}
return NULL;
}
/* DB layout:
* | 0 | storage_id
* | 1 | from
@ -416,13 +430,20 @@ void linphone_core_call_log_storage_close(LinphoneCore *lc) {
* | 11 | refkey
*/
static int create_call_log(void *data, int argc, char **argv, char **colName) {
bctbx_list_t **list = (bctbx_list_t **)data;
CallLogStorageResult *clsres = (CallLogStorageResult *)data;
LinphoneAddress *from;
LinphoneAddress *to;
LinphoneCallDir dir;
LinphoneCallLog *log;
unsigned int storage_id = (unsigned int)atoi(argv[0]);
log = find_call_log_by_storage_id(clsres->core->call_logs, storage_id);
if (log != NULL) {
clsres->result = bctbx_list_append(clsres->result, linphone_call_log_ref(log));
return 0;
}
from = linphone_address_new(argv[1]);
to = linphone_address_new(argv[2]);
@ -449,7 +470,7 @@ static int create_call_log(void *data, int argc, char **argv, char **colName) {
}
}
*list = bctbx_list_append(*list, log);
clsres->result = bctbx_list_append(clsres->result, log);
return 0;
error:
@ -463,10 +484,10 @@ error:
return 0;
}
static void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, bctbx_list_t **list) {
static void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, CallLogStorageResult *clsres) {
char* errmsg = NULL;
int ret;
ret = sqlite3_exec(db, stmt, create_call_log, list, &errmsg);
ret = sqlite3_exec(db, stmt, create_call_log, clsres, &errmsg);
if (ret != SQLITE_OK) {
ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg);
sqlite3_free(errmsg);
@ -517,31 +538,13 @@ void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log) {
}
}
static void copy_user_data_from_existing_log(bctbx_list_t *existing_logs, LinphoneCallLog *log) {
while (existing_logs) {
LinphoneCallLog *existing_log = (LinphoneCallLog *)existing_logs->data;
if (existing_log->storage_id == log->storage_id) {
log->user_data = existing_log->user_data;
break;
}
existing_logs = bctbx_list_next(existing_logs);
}
}
static void copy_user_data_from_existing_logs(bctbx_list_t *existing_logs, bctbx_list_t *new_logs) {
while (new_logs) {
LinphoneCallLog *new_log = (LinphoneCallLog *)new_logs->data;
copy_user_data_from_existing_log(existing_logs, new_log);
new_logs = bctbx_list_next(new_logs);
}
}
const bctbx_list_t *linphone_core_get_call_history(LinphoneCore *lc) {
char *buf;
uint64_t begin,end;
bctbx_list_t *result = NULL;
CallLogStorageResult clsres;
if (!lc || lc->logs_db == NULL) return NULL;
if (lc->call_logs != NULL) return lc->call_logs;
if (lc->max_call_logs != LINPHONE_MAX_CALL_HISTORY_UNLIMITED){
buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC LIMIT %i", lc->max_call_logs);
@ -549,19 +552,15 @@ const bctbx_list_t *linphone_core_get_call_history(LinphoneCore *lc) {
buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC");
}
clsres.core = lc;
clsres.result = NULL;
begin = ortp_get_cur_time_ms();
linphone_sql_request_call_log(lc->logs_db, buf, &result);
linphone_sql_request_call_log(lc->logs_db, buf, &clsres);
end = ortp_get_cur_time_ms();
ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
sqlite3_free(buf);
if (lc->call_logs) {
copy_user_data_from_existing_logs(lc->call_logs, result);
}
lc->call_logs = bctbx_list_free_with_data(lc->call_logs, (void (*)(void*))linphone_call_log_unref);
lc->call_logs = result;
lc->call_logs = clsres.result;
return lc->call_logs;
}
@ -610,7 +609,7 @@ bctbx_list_t * linphone_core_get_call_history_for_address(LinphoneCore *lc, cons
char *buf;
char *sipAddress;
uint64_t begin,end;
bctbx_list_t *result = NULL;
CallLogStorageResult clsres;
if (!lc || lc->logs_db == NULL || addr == NULL) return NULL;
@ -618,43 +617,39 @@ bctbx_list_t * linphone_core_get_call_history_for_address(LinphoneCore *lc, cons
sipAddress = linphone_address_as_string_uri_only(addr);
buf = sqlite3_mprintf("SELECT * FROM call_history WHERE caller LIKE '%%%q%%' OR callee LIKE '%%%q%%' ORDER BY id DESC", sipAddress, sipAddress); // The '%%%q%%' takes care of the eventual presence of a display name
clsres.core = lc;
clsres.result = NULL;
begin = ortp_get_cur_time_ms();
linphone_sql_request_call_log(lc->logs_db, buf, &result);
linphone_sql_request_call_log(lc->logs_db, buf, &clsres);
end = ortp_get_cur_time_ms();
ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
sqlite3_free(buf);
ms_free(sipAddress);
if (lc->call_logs) {
copy_user_data_from_existing_logs(lc->call_logs, result);
}
return result;
return clsres.result;
}
LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) {
char *buf;
uint64_t begin,end;
bctbx_list_t *list = NULL;
LinphoneCallLog* result = NULL;
CallLogStorageResult clsres;
LinphoneCallLog *result = NULL;
if (!lc || lc->logs_db == NULL) return NULL;
/*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/
buf = sqlite3_mprintf("SELECT * FROM call_history WHERE direction = 0 ORDER BY id DESC LIMIT 1");
clsres.core = lc;
clsres.result = NULL;
begin = ortp_get_cur_time_ms();
linphone_sql_request_call_log(lc->logs_db, buf, &list);
linphone_sql_request_call_log(lc->logs_db, buf, &clsres);
end = ortp_get_cur_time_ms();
ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
sqlite3_free(buf);
if (list) {
result = (LinphoneCallLog*)list->data;
}
if (lc->call_logs && result) {
copy_user_data_from_existing_log(lc->call_logs, result);
if (clsres.result != NULL) {
result = (LinphoneCallLog *)bctbx_list_get_data(clsres.result);
}
return result;
@ -663,7 +658,7 @@ LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) {
LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, const char *call_id) {
char *buf;
uint64_t begin,end;
bctbx_list_t *list = NULL;
CallLogStorageResult clsres;
LinphoneCallLog* result = NULL;
if (!lc || lc->logs_db == NULL) return NULL;
@ -671,18 +666,16 @@ LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, con
/*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/
buf = sqlite3_mprintf("SELECT * FROM call_history WHERE call_id = '%q' ORDER BY id DESC LIMIT 1", call_id);
clsres.core = lc;
clsres.result = NULL;
begin = ortp_get_cur_time_ms();
linphone_sql_request_call_log(lc->logs_db, buf, &list);
linphone_sql_request_call_log(lc->logs_db, buf, &clsres);
end = ortp_get_cur_time_ms();
ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
sqlite3_free(buf);
if (list) {
result = (LinphoneCallLog*)list->data;
}
if (lc->call_logs && result) {
copy_user_data_from_existing_log(lc->call_logs, result);
if (clsres.result != NULL) {
result = (LinphoneCallLog *)bctbx_list_get_data(clsres.result);
}
return result;

View file

@ -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;

View file

@ -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) {

View file

@ -924,7 +924,7 @@ static void _linphone_conference_params_uninit(LinphoneConferenceParams *params)
static void _linphone_conference_params_clone(LinphoneConferenceParams *params, const LinphoneConferenceParams *orig);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneConferenceParams);
BELLE_SIP_DECLARE_VPTR(LinphoneConferenceParams);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneConferenceParams);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneConferenceParams, belle_sip_object_t,
_linphone_conference_params_uninit, // uninit
_linphone_conference_params_clone, // clone
@ -983,7 +983,7 @@ struct _LinphoneConference {
static void _linphone_conference_uninit(LinphoneConference *conf);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneConference);
BELLE_SIP_DECLARE_VPTR(LinphoneConference);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneConference);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneConference, belle_sip_object_t,
_linphone_conference_uninit, // uninit
NULL, // clone

View file

@ -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;
}

View file

@ -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);

View file

@ -38,7 +38,7 @@ static void _linphone_info_message_uninit(LinphoneInfoMessage *im);
static void _linphone_info_message_copy(LinphoneInfoMessage *im, const LinphoneInfoMessage *orig);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneInfoMessage);
BELLE_SIP_DECLARE_VPTR(LinphoneInfoMessage);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneInfoMessage);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneInfoMessage, belle_sip_object_t,
_linphone_info_message_uninit, // uninit
_linphone_info_message_copy, // clone

View file

@ -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);
@ -5045,8 +5047,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);
@ -5105,7 +5109,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;

View file

@ -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);
}
}

View file

@ -1282,7 +1282,7 @@ public:
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);
statsobj = env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)call, (jlong)stats);
statsobj = env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)stats);
callobj = getCall(env, call);
env->CallVoidMethod(lcData->listener, ljb->callStatsUpdatedId, lcData->core, callobj, statsobj);
handle_possible_java_exception(env, lcData->listener);
@ -3478,6 +3478,14 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCallImpl_getStats(JNIEn
return stats ? env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)stats) : NULL;
}
JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCallImpl_getCore(JNIEnv* env
,jobject thiz
,jlong ptr) {
LinphoneCall *call=(LinphoneCall*)ptr;
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data(linphone_call_get_core(call));
return ljb->getCore();
}
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCallLog( JNIEnv* env
,jobject thiz
,jlong ptr) {
@ -5058,8 +5066,8 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteParams(JNIEnv
return (jlong) linphone_call_params_copy(linphone_call_get_remote_params((LinphoneCall*)lc));
}
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParamsCopy(JNIEnv *env, jobject thiz, jlong lc){
return (jlong) linphone_call_params_copy(linphone_call_get_current_params((LinphoneCall*)lc));
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParams(JNIEnv *env, jobject thiz, jlong lc){
return (jlong) linphone_call_params_ref((LinphoneCallParams*)linphone_call_get_current_params((LinphoneCall*)lc));
}
extern "C" void Java_org_linphone_core_LinphoneCallImpl_enableCamera(JNIEnv *env, jobject thiz, jlong lc, jboolean b){
@ -7278,7 +7286,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;
}

View file

@ -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);
@ -626,6 +631,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;
@ -1103,6 +1109,7 @@ struct _LinphoneCore
struct _LinphoneEvent{
belle_sip_object_t base;
LinphoneErrorInfo *ei;
LinphoneSubscriptionDir dir;
LinphoneCore *lc;
SalOp *op;
@ -1516,10 +1523,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)
{
@ -1608,7 +1612,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

View file

@ -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) {

View file

@ -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);
/**
* @}
*/

View file

@ -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);

View file

@ -201,6 +201,16 @@ public interface LinphoneCall {
**/
LinphoneCallParams getRemoteParams();
/**
* Get call's effective parameters, resulting from SDP offer/answer.
**/
LinphoneCallParams getCurrentParams();
/**
*
* Same as getCurrentParams(), but deprecated.
* @deprecated
**/
LinphoneCallParams getCurrentParamsCopy();
void enableCamera(boolean enabled);

View file

@ -21,15 +21,17 @@ package org.linphone.core;
class LinphoneCallImpl implements LinphoneCall {
protected final long nativePtr;
boolean ownPtr = false;
Object userData;
LinphoneCore mCore;
native private void finalize(long nativePtr);
native private long getCallLog(long nativePtr);
private native boolean isIncoming(long nativePtr);
native private long getRemoteAddress(long nativePtr);
native private int getState(long nativePtr);
private native long getCurrentParamsCopy(long nativePtr);
private native long getCurrentParams(long nativePtr);
private native long getRemoteParams(long nativePtr);
private native void enableCamera(long nativePtr, boolean enabled);
private native boolean cameraEnabled(long nativePtr);
@ -45,12 +47,14 @@ class LinphoneCallImpl implements LinphoneCall {
private native void setListener(long ptr, LinphoneCallListener listener);
native private long getDiversionAddress(long nativePtr);
native private Object getStats(long nativePtr, int stream_type);
native private LinphoneCore getCore(long nativePtr);
/*
* This method must always be called from JNI, nothing else.
*/
private LinphoneCallImpl(long aNativePtr) {
nativePtr = aNativePtr;
mCore = getCore(nativePtr);
}
protected void finalize() throws Throwable {
finalize(nativePtr);
@ -65,10 +69,14 @@ class LinphoneCallImpl implements LinphoneCall {
}
public LinphoneCallStats getAudioStats() {
return (LinphoneCallStats)getStats(nativePtr, 0);
synchronized(mCore){
return (LinphoneCallStats)getStats(nativePtr, 0);
}
}
public LinphoneCallStats getVideoStats() {
return (LinphoneCallStats)getStats(nativePtr, 1);
synchronized(mCore){
return (LinphoneCallStats)getStats(nativePtr, 1);
}
}
public CallDirection getDirection() {
return isIncoming(nativePtr)?CallDirection.Incoming:CallDirection.Outgoing;
@ -84,8 +92,11 @@ class LinphoneCallImpl implements LinphoneCall {
public State getState() {
return LinphoneCall.State.fromInt(getState(nativePtr));
}
public LinphoneCallParams getCurrentParamsCopy() {
return new LinphoneCallParamsImpl(getCurrentParamsCopy(nativePtr));
public LinphoneCallParams getCurrentParams() {
return new LinphoneCallParamsImpl(getCurrentParams(nativePtr));
}
public LinphoneCallParams getCurrentParamsCopy(){
return getCurrentParams();
}
public LinphoneCallParams getRemoteParams() {
long remoteParamsPtr = getRemoteParams(nativePtr);

View file

@ -2893,6 +2893,7 @@ static void call_established_with_complex_rejected_operation(void) {
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
bool_t call_ok=FALSE;
LinphoneCallParams *params;
LinphoneInfoMessage *info;
BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
if (call_ok){
@ -2906,7 +2907,9 @@ static void call_established_with_complex_rejected_operation(void) {
linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/
/*just to authenticate marie*/
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc));
info = linphone_core_create_info_message(marie->lc);
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info);
linphone_info_message_unref(info);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1));
BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived,1, int, "%d");
/*to give time for 200ok to arrive*/
@ -2926,8 +2929,9 @@ static void call_established_with_complex_rejected_operation(void) {
check_call_state(marie,LinphoneCallStreamsRunning);
linphone_call_update(linphone_core_get_current_call(pauline->lc),linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)));
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc));
info = linphone_core_create_info_message(marie->lc);
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info);
linphone_info_message_unref(info);
params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc));
sal_enable_pending_trans_checking(marie->lc->sal,FALSE); /*to allow // transactions*/
@ -2958,7 +2962,7 @@ static void call_established_with_rejected_info_during_reinvite(void) {
BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
if (call_ok){
LinphoneInfoMessage *info;
BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,1));
BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,1));
@ -2968,15 +2972,18 @@ static void call_established_with_rejected_info_during_reinvite(void) {
linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/
/*just to authenticate marie*/
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc));
info = linphone_core_create_info_message(marie->lc);
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info);
linphone_info_message_unref(info);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1));
BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived,1, int, "%d");
/*to give time for 200ok to arrive*/
wait_for_until(marie->lc,pauline->lc,NULL,0,1000);
//sal_enable_pending_trans_checking(marie->lc->sal,FALSE); /*to allow // transactions*/
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc));
info = linphone_core_create_info_message(marie->lc);
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),info);
linphone_info_message_unref(info);
//sal_set_send_error(marie->lc->sal, -1); /*to avoid 491 pending to be sent*/
@ -3116,6 +3123,7 @@ static void call_established_with_rejected_reinvite_with_error_base(bool_t trans
if (trans_pending) {
LinphoneInfoMessage * info = linphone_core_create_info_message(pauline->lc);
linphone_call_send_info_message(linphone_core_get_current_call(pauline->lc),info);
linphone_info_message_unref(info);
} else
sal_enable_unconditional_answer(marie->lc->sal,TRUE);
@ -5154,8 +5162,9 @@ static void call_logs_sqlite_storage(void) {
logs = linphone_core_get_call_history_for_address(marie->lc, linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc)));
if (BC_ASSERT_TRUE(bctbx_list_size(logs) == 1)) {
const char *call_id;
const char *ref_key = linphone_call_log_get_ref_key(call_log);
call_log = logs->data;
const char *ref_key;
call_log = (LinphoneCallLog *)bctbx_list_get_data(logs);
ref_key = linphone_call_log_get_ref_key(call_log);
BC_ASSERT_EQUAL(linphone_call_log_get_dir(call_log), LinphoneCallOutgoing, int, "%d");
BC_ASSERT_LOWER(linphone_call_log_get_duration(call_log), 2, int, "%d");
BC_ASSERT_TRUE(linphone_address_equal(

View file

@ -827,6 +827,71 @@ static void video_call_using_policy_AVPF_implicit_caller_and_callee(void) {
linphone_core_manager_destroy(caller);
}
static void video_call_established_by_reinvite_with_implicit_avpf(void) {
LinphoneCoreManager *callee = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *caller = linphone_core_manager_new(transport_supported(LinphoneTransportTcp) ? "pauline_rc" : "pauline_tcp_rc");
LinphoneVideoPolicy policy;
LinphoneCall * caller_call, *callee_call;
LinphoneCallParams *params;
policy.automatically_initiate=FALSE;
policy.automatically_accept=FALSE;
linphone_core_set_video_policy(callee->lc,&policy);
policy.automatically_initiate=TRUE;
policy.automatically_accept=TRUE;
linphone_core_set_video_policy(caller->lc,&policy);
linphone_core_enable_video_display(callee->lc, TRUE);
linphone_core_enable_video_capture(callee->lc, TRUE);
linphone_proxy_config_set_avpf_mode(linphone_core_get_default_proxy_config(callee->lc), LinphoneAVPFEnabled);
linphone_core_enable_video_display(caller->lc, TRUE);
linphone_core_enable_video_capture(caller->lc, TRUE);
linphone_core_set_video_device(caller->lc,liblinphone_tester_mire_id);
linphone_core_set_video_device(callee->lc,liblinphone_tester_mire_id);
caller_call = linphone_core_invite_address(caller->lc, callee->identity);
if (BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallIncomingReceived,1))){
callee_call = linphone_core_get_current_call(callee->lc);
linphone_core_accept_call(callee->lc, linphone_core_get_current_call(callee->lc));
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallStreamsRunning,1));
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_LinphoneCallStreamsRunning,1));
BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(callee_call)));
BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(caller_call)));
/*then callee adds video*/
params = linphone_core_create_call_params(callee->lc, callee_call);
linphone_call_params_enable_video(params, TRUE);
linphone_call_update(callee_call, params);
linphone_call_params_unref(params);
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallUpdating,1));
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_LinphoneCallUpdatedByRemote,1));
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(callee_call)));
BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(caller_call)));
linphone_call_set_next_video_frame_decoded_callback(caller_call,linphone_call_iframe_decoded_cb,caller->lc);
linphone_call_set_next_video_frame_decoded_callback(callee_call,linphone_call_iframe_decoded_cb,callee->lc);
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_IframeDecoded,1));
BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_IframeDecoded,1));
BC_ASSERT_TRUE(media_stream_avpf_enabled((MediaStream*)caller_call->videostream));
BC_ASSERT_TRUE(media_stream_avpf_enabled((MediaStream*)callee_call->videostream));
}
end_call(caller, callee);
linphone_core_manager_destroy(callee);
linphone_core_manager_destroy(caller);
}
static void video_call_base_avpf(LinphoneCoreManager *caller, LinphoneCoreManager *callee, bool_t using_policy, LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) {
linphone_core_set_avpf_mode(caller->lc, LinphoneAVPFEnabled);
linphone_core_set_avpf_mode(callee->lc, LinphoneAVPFEnabled);
@ -1441,6 +1506,7 @@ static void multiple_early_media(void) {
/*send an INFO in reverse side to check that dialogs are properly established*/
info=linphone_core_create_info_message(marie1->lc);
linphone_call_send_info_message(marie1_call,info);
linphone_info_message_unref(info);
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_inforeceived,1,3000));
}
@ -1950,6 +2016,7 @@ test_t call_video_tests[] = {
TEST_NO_TAG("Simple video call disable implicit AVPF on caller", video_call_disable_implicit_AVPF_on_caller),
TEST_NO_TAG("Simple video call AVPF to implicit AVPF", video_call_AVPF_to_implicit_AVPF),
TEST_NO_TAG("Simple video call implicit AVPF to AVPF", video_call_implicit_AVPF_to_AVPF),
TEST_NO_TAG("Video added by reINVITE, with implicit AVPF", video_call_established_by_reinvite_with_implicit_avpf),
TEST_NO_TAG("Simple video call", video_call),
TEST_NO_TAG("Simple video call without rtcp",video_call_without_rtcp),
TEST_NO_TAG("Simple ZRTP video call", video_call_zrtp),

View file

@ -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));
}
}

View file

@ -503,6 +503,7 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void
/* send an INFO in reverse side to check that dialogs are properly established */
info = linphone_core_create_info_message(marie1->lc);
linphone_call_send_info_message(marie1_call, info);
linphone_info_message_unref(info);
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_inforeceived, 1, 3000));
}

View file

@ -47,6 +47,7 @@ set_target_properties(linphone++ PROPERTIES SOVERSION ${LINPHONE_SO_VERSION})
install(TARGETS linphone++ EXPORT LinphoneCxxTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES object.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++