Store chat message in database before file upload so that if the file upload fails we can try sending the chat message an other time.

This commit is contained in:
Ghislain MARY 2017-02-02 17:59:44 +01:00
parent 01e990259d
commit 50f4e52966
7 changed files with 230 additions and 63 deletions

View file

@ -329,7 +329,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallLog, belle_sip_object_t,
#ifdef SQLITE_STORAGE_ENABLED
static void linphone_create_table(sqlite3* db) {
static void linphone_create_call_log_table(sqlite3* db) {
char* errmsg=NULL;
int ret;
ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS call_history ("
@ -386,7 +386,7 @@ void linphone_core_call_log_storage_init(LinphoneCore *lc) {
return;
}
linphone_create_table(db);
linphone_create_call_log_table(db);
linphone_update_call_log_table(db);
lc->logs_db = db;

View file

@ -343,6 +343,29 @@ void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud) {
cr->user_data = ud;
}
void linphone_chat_room_add_transient_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
if (bctbx_list_find(msg->chat_room->transient_messages, msg) == NULL) {
cr->transient_messages = bctbx_list_append(cr->transient_messages, linphone_chat_message_ref(msg));
}
}
void linphone_chat_room_remove_transient_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
if (bctbx_list_find(msg->chat_room->transient_messages, msg) != NULL) {
cr->transient_messages = bctbx_list_remove(cr->transient_messages, msg);
linphone_chat_message_unref(msg);
}
}
static void store_or_update_chat_message(LinphoneChatMessage *msg) {
if (msg->storage_id != 0) {
/* The message has already been stored (probably because of file transfer), update it */
linphone_chat_message_store_update(msg);
} else {
/* Store the new message */
msg->storage_id = linphone_chat_message_store(msg);
}
}
void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
int retval = -1;
LinphoneCore *lc = cr->lc;
@ -363,8 +386,10 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
if (msg->file_transfer_information != NULL && msg->content_type == NULL) {
/* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */
if (linphone_chat_room_upload_file(msg) == 0) {
// add to transient list only if message is going out
cr->transient_messages = bctbx_list_append(cr->transient_messages, linphone_chat_message_ref(msg));
/* Add to transient list only if message is going out */
linphone_chat_room_add_transient_message(cr, msg);
/* Store the message so that even if the upload is stopped, it can be done again */
msg->storage_id = linphone_chat_message_store(msg);
} else {
linphone_chat_message_unref(msg);
return;
@ -380,8 +405,8 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
message_not_encrypted = ms_strdup(msg->message);
}
// add to transient list
cr->transient_messages = bctbx_list_append(cr->transient_messages, linphone_chat_message_ref(msg));
/* Add to transient list */
linphone_chat_room_add_transient_message(cr, msg);
msg->time = ms_time(0);
if (lp_config_get_int(cr->lc->config, "sip", "chat_use_call_dialogs", 0) != 0) {
if ((call = linphone_core_get_call_by_remote_address(cr->lc, cr->peer)) != NULL) {
@ -433,6 +458,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);
store_or_update_chat_message(msg);
linphone_chat_message_update_state(msg, LinphoneChatMessageStateNotDelivered);
linphone_chat_message_unref(msg);
return;
@ -459,7 +485,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
msg->message = ms_strdup(message_not_encrypted);
}
msg->message_id = ms_strdup(sal_op_get_call_id(op)); /* must be known at that time */
msg->storage_id = linphone_chat_message_store(msg);
store_or_update_chat_message(msg);
if (cr->is_composing == LinphoneIsComposingActive) {
cr->is_composing = LinphoneIsComposingIdle;
@ -474,8 +500,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
if (call && call->op == op) {
/*In this case, chat delivery status is not notified, so unrefing chat message right now*/
/*Might be better fixed by delivering status, but too costly for now*/
msg->chat_room->transient_messages = bctbx_list_remove(msg->chat_room->transient_messages, msg);
linphone_chat_message_unref(msg);
linphone_chat_room_remove_transient_message(msg->chat_room, msg);
linphone_chat_message_unref(msg);
return;
}
@ -493,9 +518,8 @@ void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMe
if (msg->state == LinphoneChatMessageStateDelivered || msg->state == LinphoneChatMessageStateNotDelivered) {
if (bctbx_list_find(msg->chat_room->transient_messages, msg) != NULL) {
// msg is not transient anymore, we can remove it from our transient list and unref it
msg->chat_room->transient_messages = bctbx_list_remove(msg->chat_room->transient_messages, msg);
linphone_chat_room_add_weak_message(msg->chat_room, msg);
linphone_chat_message_unref(msg);
linphone_chat_room_remove_transient_message(msg->chat_room, msg);
} else {
// msg has already been removed from the transient messages, do nothing. */
}

View file

@ -48,6 +48,7 @@ static void linphone_chat_message_process_io_error_upload(void *data, const bell
ms_error("I/O Error during file upload of msg [%p]", msg);
linphone_chat_message_update_state(msg, LinphoneChatMessageStateNotDelivered);
_release_http_request(msg);
linphone_chat_room_remove_transient_message(msg->chat_room, msg);
linphone_chat_message_unref(msg);
}
@ -56,6 +57,7 @@ static void linphone_chat_message_process_auth_requested_upload(void *data, bell
ms_error("Error during file upload: auth requested for msg [%p]", msg);
linphone_chat_message_update_state(msg, LinphoneChatMessageStateNotDelivered);
_release_http_request(msg);
linphone_chat_room_remove_transient_message(msg->chat_room, msg);
linphone_chat_message_unref(msg);
}
@ -260,7 +262,7 @@ static void linphone_chat_message_process_response_from_post_file(void *data,
linphone_chat_room_upload_file(msg);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(msg->http_request), BELLE_SIP_BODY_HANDLER(bh));
linphone_chat_message_unref(msg);
} else if (code == 200) { /* file has been uplaoded correctly, get server reply and send it */
} else if (code == 200) { /* file has been uploaded correctly, get server reply and send it */
const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
if (body && strlen(body) > 0) {
/* if we have an encryption key for the file, we must insert it into the msg and restore the correct

View file

@ -1152,7 +1152,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t,
#ifdef SQLITE_STORAGE_ENABLED
static void linphone_create_table(sqlite3* db) {
static void linphone_create_friends_table(sqlite3* db) {
char* errmsg = NULL;
int ret;
ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends ("
@ -1187,7 +1187,7 @@ static void linphone_create_table(sqlite3* db) {
}
}
static bool_t linphone_update_table(sqlite3* db) {
static bool_t linphone_update_friends_table(sqlite3* db) {
static sqlite3_stmt *stmt_version;
int database_user_version = -1;
char *errmsg = NULL;
@ -1246,8 +1246,8 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) {
return;
}
linphone_create_table(db);
if (linphone_update_table(db)) {
linphone_create_friends_table(db);
if (linphone_update_friends_table(db)) {
// After updating schema, database need to be closed/reopenned
sqlite3_close(db);
_linphone_sqlite3_open(lc->friends_db_file, &db);

View file

@ -247,7 +247,7 @@ static int create_chat_message(void *data, int argc, char **argv, char **colName
new_message->external_body_url= ms_strdup(argv[8]);
new_message->appdata = ms_strdup(argv[10]);
new_message->message_id = ms_strdup(argv[12]);
new_message->content_type = ms_strdup(argv[13]);
linphone_chat_message_set_content_type(new_message, argv[13]);
new_message->is_secured = (bool_t)atoi(argv[14]);
if (argv[11] != NULL) {
@ -370,6 +370,41 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
return id;
}
void linphone_chat_message_store_update(LinphoneChatMessage *msg) {
LinphoneCore *lc = linphone_chat_room_get_core(msg->chat_room);
if (lc->db) {
char *peer;
char *local_contact;
char *buf;
peer = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));
local_contact = linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));
buf = sqlite3_mprintf("UPDATE history SET"
" localContact = %Q,"
" remoteContact = %Q,"
" message = %Q,"
" status = %i,"
" appdata = %Q,"
" messageId = %Q,"
" content_type = %Q"
" WHERE (id = %u);",
local_contact,
peer,
msg->message,
msg->state,
msg->appdata,
msg->message_id,
msg->content_type,
msg->storage_id
);
linphone_sql_request(lc->db, buf);
sqlite3_free(buf);
ms_free(local_contact);
ms_free(peer);
}
}
void linphone_chat_message_store_state(LinphoneChatMessage *msg){
LinphoneCore *lc=msg->chat_room->lc;
if (lc->db){
@ -563,6 +598,7 @@ bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int sta
while (it) {
LinphoneChatMessage* msg = it->data;
if (msg->dir == LinphoneChatMessageOutgoing) {
if (msg->from != NULL) linphone_address_unref(msg->from);
msg->from = linphone_address_ref(local_addr);
} else {
msg->to = linphone_address_ref(local_addr);
@ -604,7 +640,7 @@ LinphoneChatMessage * linphone_chat_room_find_message(LinphoneChatRoom *cr, cons
return cm;
}
void linphone_create_table(sqlite3* db){
static void linphone_create_history_table(sqlite3* db){
char* errmsg=NULL;
int ret;
ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS history ("
@ -686,7 +722,7 @@ static void linphone_migrate_timestamps(sqlite3* db){
}
}
void linphone_update_table(sqlite3* db) {
static void linphone_update_history_table(sqlite3* db) {
char* errmsg=NULL;
char *buf;
int ret;
@ -764,6 +800,7 @@ void linphone_update_table(sqlite3* db) {
ret = sqlite3_exec(db, "ALTER TABLE history ADD COLUMN messageId TEXT;", NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
ms_message("Table already up to date: %s", errmsg);
sqlite3_free(errmsg);
} else {
ms_message("Table history updated successfully for messageId data.");
}
@ -777,6 +814,7 @@ void linphone_update_table(sqlite3* db) {
ret = sqlite3_exec(db, "ALTER TABLE history ADD COLUMN content_type TEXT;", NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
ms_message("Table already up to date: %s", errmsg);
sqlite3_free(errmsg);
} else {
ms_message("Table history updated successfully for content_type data.");
}
@ -785,11 +823,20 @@ void linphone_update_table(sqlite3* db) {
ret = sqlite3_exec(db, "ALTER TABLE history ADD COLUMN is_secured INTEGER DEFAULT 0;", NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
ms_message("Table already up to date: %s", errmsg);
sqlite3_free(errmsg);
} else {
ms_message("Table history updated successfully for is_secured data.");
}
}
static void linphone_fix_outgoing_messages_state(sqlite3* db) {
/* Convert Idle and InProgress states of outgoing messages to NotDelivered */
char *buf = sqlite3_mprintf("UPDATE history SET status=%i WHERE direction=%i AND (status=%i OR status=%i);",
LinphoneChatMessageStateNotDelivered, LinphoneChatMessageOutgoing, LinphoneChatMessageStateIdle, LinphoneChatMessageStateInProgress);
linphone_sql_request(db, buf);
sqlite3_free(buf);
}
void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) {
char *buf;
@ -837,8 +884,9 @@ void linphone_core_message_storage_init(LinphoneCore *lc){
linphone_message_storage_activate_debug(db, lc->debug_storage);
linphone_create_table(db);
linphone_update_table(db);
linphone_create_history_table(db);
linphone_update_history_table(db);
linphone_fix_outgoing_messages_state(db);
lc->db=db;
// Create a chatroom for each contact in the chat history

View file

@ -621,6 +621,8 @@ int linphone_chat_room_upload_file(LinphoneChatMessage *msg);
void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void);
LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call);
void linphone_chat_room_add_transient_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
void linphone_chat_room_remove_transient_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
/**/
struct _LinphoneProxyConfig
@ -1238,6 +1240,7 @@ int _linphone_sqlite3_open(const char *db_file, sqlite3 **db);
sqlite3 * linphone_message_storage_init(void);
void linphone_message_storage_init_chat_rooms(LinphoneCore *lc);
#endif
void linphone_chat_message_store_update(LinphoneChatMessage *msg);
void linphone_chat_message_store_state(LinphoneChatMessage *msg);
void linphone_chat_message_store_appdata(LinphoneChatMessage* msg);
void linphone_core_message_storage_init(LinphoneCore *lc);

View file

@ -218,12 +218,12 @@ void compare_files(const char *path1, const char *path2) {
if (buf2) ms_free(buf2);
}
LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) {
LinphoneChatMessage* create_message_from_sintel_trailer(LinphoneChatRoom *chat_room) {
FILE *file_to_send = NULL;
LinphoneChatMessageCbs *cbs;
LinphoneContent* content;
LinphoneChatMessage* msg;
char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg");
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
size_t file_size;
file_to_send = fopen(send_filepath, "rb");
fseek(file_to_send, 0, SEEK_END);
@ -231,11 +231,11 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) {
fseek(file_to_send, 0, SEEK_SET);
content = linphone_core_create_content(chat_room->lc);
belle_sip_object_set_name(&content->base, "nowebcam content");
linphone_content_set_type(content,"image");
linphone_content_set_subtype(content,"jpeg");
belle_sip_object_set_name(&content->base, "sintel trailer content");
linphone_content_set_type(content,"video");
linphone_content_set_subtype(content,"mkv");
linphone_content_set_size(content,file_size); /*total size to be transfered*/
linphone_content_set_name(content,"nowebcamVGA.jpg");
linphone_content_set_name(content,"sintel_trailer_opus_h264.mkv");
msg = linphone_chat_room_create_file_transfer_message(chat_room, content);
cbs = linphone_chat_message_get_callbacks(msg);
@ -246,21 +246,21 @@ LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) {
BC_ASSERT_PTR_NOT_NULL(linphone_chat_message_get_user_data(msg));
linphone_content_unref(content);
ms_free(send_filepath);
bc_free(send_filepath);
return msg;
}
LinphoneChatMessage* create_file_transfer_message_from_nowebcam(LinphoneChatRoom *chat_room) {
LinphoneChatMessage* create_file_transfer_message_from_sintel_trailer(LinphoneChatRoom *chat_room) {
LinphoneChatMessageCbs *cbs;
LinphoneContent* content;
LinphoneChatMessage* msg;
char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg");
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
content = linphone_core_create_content(chat_room->lc);
belle_sip_object_set_name(&content->base, "nowebcam content");
linphone_content_set_type(content,"image");
linphone_content_set_subtype(content,"jpeg");
linphone_content_set_name(content,"nowebcamVGA.jpg");
belle_sip_object_set_name(&content->base, "sintel trailer content");
linphone_content_set_type(content,"video");
linphone_content_set_subtype(content,"mkv");
linphone_content_set_name(content,"sintel_trailer_opus_h264.mkv");
msg = linphone_chat_room_create_file_transfer_message(chat_room, content);
linphone_chat_message_set_file_transfer_filepath(msg, send_filepath);
@ -270,7 +270,7 @@ LinphoneChatMessage* create_file_transfer_message_from_nowebcam(LinphoneChatRoom
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication);
linphone_content_unref(content);
ms_free(send_filepath);
bc_free(send_filepath);
return msg;
}
@ -457,7 +457,7 @@ static void text_message_with_external_body(void) {
void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, bool_t upload_error, bool_t download_error,
bool_t use_file_body_handler_in_upload, bool_t use_file_body_handler_in_download, bool_t download_from_history) {
char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg");
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
char *receive_filepath = bc_tester_file("receive_file.dump");
LinphoneChatRoom* chat_room;
LinphoneChatMessage* msg;
@ -475,16 +475,28 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
/* create a file transfer msg */
if (use_file_body_handler_in_upload) {
msg = create_file_transfer_message_from_nowebcam(chat_room);
msg = create_file_transfer_message_from_sintel_trailer(chat_room);
} else {
msg = create_message_from_nowebcam(chat_room);
msg = create_message_from_sintel_trailer(chat_room);
}
linphone_chat_room_send_chat_message(chat_room,msg);
if (upload_error) {
int chat_room_size = 0;
bctbx_list_t *history;
/*wait for file to be 25% uploaded and simulate a network error*/
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25));
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25, 60000));
/* Check that the message is already in the chat room history during file upload */
chat_room_size = linphone_chat_room_get_history_size(chat_room);
BC_ASSERT_EQUAL(chat_room_size, 1, int, "%d");
if (chat_room_size == 1) {
history = linphone_chat_room_get_history(chat_room, 0);
LinphoneChatMessage *sent_msg = (LinphoneChatMessage *)bctbx_list_get_data(history);
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateInProgress, int, "%d");
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
}
sal_set_send_error(pauline->lc->sal, -1);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
@ -496,8 +508,18 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
linphone_core_refresh_registers(pauline->lc); /*to make sure registration is back in registered and so it can be later unregistered*/
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneRegistrationOk,pauline->stat.number_of_LinphoneRegistrationOk+1));
/* Check that the message is in the chat room history even if the file upload failed */
chat_room_size = linphone_chat_room_get_history_size(chat_room);
BC_ASSERT_EQUAL(chat_room_size, 1, int, "%d");
if (chat_room_size == 1) {
history = linphone_chat_room_get_history(chat_room, 0);
LinphoneChatMessage *sent_msg = (LinphoneChatMessage *)bctbx_list_get_data(history);
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateNotDelivered, int, "%d");
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
}
} else {
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000));
if (marie->stat.last_received_chat_message) {
LinphoneChatMessage *recv_msg;
if (download_from_history) {
@ -538,7 +560,7 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
end:
bctbx_list_free_with_data(msg_list, (bctbx_list_free_func)linphone_chat_message_unref);
remove(receive_filepath);
ms_free(send_filepath);
bc_free(send_filepath);
bc_free(receive_filepath);
}
@ -593,11 +615,11 @@ static void transfer_message_upload_cancelled(void) {
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
msg = create_message_from_nowebcam(chat_room);
msg = create_message_from_sintel_trailer(chat_room);
linphone_chat_room_send_chat_message(chat_room,msg);
/*wait for file to be 50% uploaded and cancel the transfer */
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 50));
/*wait for file to be 25% uploaded and cancel the transfer */
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 25, 60000));
linphone_chat_message_cancel_file_transfer(msg);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
@ -621,11 +643,11 @@ static void transfer_message_download_cancelled(void) {
/* create a chatroom on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc,marie->identity);
msg = create_message_from_nowebcam(chat_room);
msg = create_message_from_sintel_trailer(chat_room);
linphone_chat_room_send_chat_message(chat_room,msg);
/* wait for marie to receive pauline's msg */
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000));
if (marie->stat.last_received_chat_message ) { /* get last msg and use it to download file */
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(marie->stat.last_received_chat_message);
@ -687,7 +709,7 @@ static void file_transfer_2_messages_simultaneously(void) {
LinphoneChatMessage* msg;
LinphoneChatMessage* msg2;
LinphoneChatMessageCbs *cbs;
char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg");
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
char *receive_filepath = bc_tester_file("receive_file.dump");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
@ -699,8 +721,8 @@ static void file_transfer_2_messages_simultaneously(void) {
/* create a chatroom on pauline's side */
pauline_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
msg = create_message_from_nowebcam(pauline_room);
msg2 = create_message_from_nowebcam(pauline_room);
msg = create_message_from_sintel_trailer(pauline_room);
msg2 = create_message_from_sintel_trailer(pauline_room);
cbs = linphone_chat_message_get_callbacks(msg2);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
@ -709,9 +731,9 @@ static void file_transfer_2_messages_simultaneously(void) {
if (bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)) == 0) {
linphone_chat_room_send_chat_message(pauline_room,msg);
linphone_chat_room_send_chat_message(pauline_room,msg2);
if (BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1))) {
if (BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000))) {
msg = linphone_chat_message_clone(marie->stat.last_received_chat_message);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,2));
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,2, 60000));
msg2 = marie->stat.last_received_chat_message;
BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)), 1, unsigned int, "%u");
if (bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)) != 1) {
@ -748,7 +770,7 @@ static void file_transfer_2_messages_simultaneously(void) {
}
linphone_core_manager_destroy(pauline);
remove(receive_filepath);
ms_free(send_filepath);
bc_free(send_filepath);
bc_free(receive_filepath);
linphone_core_manager_destroy(marie);
}
@ -1230,9 +1252,18 @@ static void lime_text_message_to_non_lime(bool_t sender_policy_mandatory, bool_t
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
//since we cannot decrypt message, we should not receive any message
if (sender_policy_mandatory || lime_key_available) {
int chat_room_size = 0;
BC_ASSERT_FALSE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
BC_ASSERT_FALSE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy, 0, int, "%d");
chat_room_size = linphone_chat_room_get_history_size(chat_room);
BC_ASSERT_EQUAL(chat_room_size, 1, int, "%d");
if (chat_room_size == 1) {
bctbx_list_t *history = linphone_chat_room_get_history(chat_room, 0);
LinphoneChatMessage *sent_msg = (LinphoneChatMessage *)bctbx_list_get_data(history);
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateNotDelivered, int, "%d");
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
}
} else {
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy, 1, int, "%d");
@ -1257,6 +1288,10 @@ static void lime_text_message_to_non_lime_preferred_policy_2(void) {
lime_text_message_to_non_lime(FALSE, FALSE);
}
static void lime_text_message_without_cache(void) {
lime_text_message_to_non_lime(TRUE, FALSE);
}
void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_stored_msg, bool_t use_file_body_handler_in_upload, bool_t use_file_body_handler_in_download) {
FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD;
LinphoneCoreManager *marie, *pauline;
@ -1264,7 +1299,7 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st
LinphoneChatMessageCbs *cbs;
char *pauline_id, *marie_id;
char *filepath;
char *send_filepath = bc_tester_res("images/nowebcamVGA.jpg");
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
char *receive_filepath = bc_tester_file("receive_file.dump");
MSList * msg_list = NULL;
@ -1311,13 +1346,13 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st
/* create a file transfer msg */
if (use_file_body_handler_in_upload) {
msg = create_file_transfer_message_from_nowebcam(linphone_core_get_chat_room(pauline->lc, marie->identity));
msg = create_file_transfer_message_from_sintel_trailer(linphone_core_get_chat_room(pauline->lc, marie->identity));
} else {
msg = create_message_from_nowebcam(linphone_core_get_chat_room(pauline->lc, marie->identity));
msg = create_message_from_sintel_trailer(linphone_core_get_chat_room(pauline->lc, marie->identity));
}
linphone_chat_room_send_chat_message(msg->chat_room, msg);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000));
if (marie->stat.last_received_chat_message ) {
LinphoneChatMessage *recv_msg;
const LinphoneContent* content;
@ -1359,7 +1394,7 @@ end:
remove("tmpZIDCacheMarie.xml");
remove("tmpZIDCachePauline.xml");
remove(receive_filepath);
ms_free(send_filepath);
bc_free(send_filepath);
bc_free(receive_filepath);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -1676,7 +1711,7 @@ static void database_migration(void) {
end:
linphone_core_manager_destroy(marie);
remove(tmp_db);
ms_free(src_db);
bc_free(src_db);
bc_free(tmp_db);
}
@ -1720,7 +1755,7 @@ end:
linphone_core_manager_destroy(marie);
linphone_address_unref(jehan_addr);
remove(tmp_db);
ms_free(src_db);
bc_free(src_db);
bc_free(tmp_db);
}
@ -1790,7 +1825,7 @@ end:
linphone_core_manager_destroy(marie);
linphone_address_unref(jehan_addr);
remove(tmp_db);
ms_free(src_db);
bc_free(src_db);
bc_free(tmp_db);
}
#endif
@ -1810,7 +1845,7 @@ static void text_status_after_destroying_chat_room(void) {
static void file_transfer_not_sent_if_invalid_url(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, "<sip:Jehan@sip.linphone.org>");
LinphoneChatMessage *msg = create_message_from_nowebcam(chatroom);
LinphoneChatMessage *msg = create_message_from_sintel_trailer(chatroom);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_core_set_file_transfer_server(marie->lc, "INVALID URL");
@ -1822,7 +1857,7 @@ static void file_transfer_not_sent_if_invalid_url(void) {
void file_transfer_io_error_base(char *server_url, bool_t destroy_room) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, "<sip:Jehan@sip.linphone.org>");
LinphoneChatMessage *msg = create_message_from_nowebcam(chatroom);
LinphoneChatMessage *msg = create_message_from_sintel_trailer(chatroom);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_core_set_file_transfer_server(marie->lc, server_url);
@ -2372,6 +2407,59 @@ void text_message_with_custom_content_type_and_lime(void) {
_text_message_with_custom_content_type(TRUE);
}
void crash_during_file_transfer(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
char *initial_db = bc_tester_file("initial.db");
char *saved_db = bc_tester_file("saved.db");
LinphoneChatRoom *chat_room;
LinphoneChatMessage *msg;
int chat_room_size = 0;
bctbx_list_t *msg_list = NULL;
/* Remove any previous files */
remove(initial_db);
remove(saved_db);
/* Globally configure an http file transfer server. */
linphone_core_set_file_transfer_server(pauline->lc, "https://www.linphone.org:444/lft.php");
linphone_core_set_chat_database_path(pauline->lc, initial_db);
/* Create a chatroom and a file transfer message on pauline's side */
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
msg = create_file_transfer_message_from_sintel_trailer(chat_room);
linphone_chat_room_send_chat_message(chat_room, msg);
/* Wait for 25% of the file to be uploaded and crash by stopping the iteration, saving the chat database and destroying the core */
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.progress_of_LinphoneFileTransfer, 25, 60000));
BC_ASSERT_EQUAL(message_tester_copy_file(initial_db, saved_db), 0, int, "%d");
linphone_chat_message_unref(msg);
linphone_core_manager_destroy(pauline);
/* Create a new core and check that the message stored in the saved database is in the not delivered state */
pauline = linphone_core_manager_new("pauline_tcp_rc");
linphone_core_set_chat_database_path(pauline->lc, saved_db);
BC_ASSERT_TRUE(wait_for(pauline->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 1));
chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity);
chat_room_size = linphone_chat_room_get_history_size(chat_room);
BC_ASSERT_EQUAL(chat_room_size, 1, int, "%d");
if (chat_room_size == 1) {
msg_list = linphone_chat_room_get_history(chat_room, 0);
LinphoneChatMessage *sent_msg = (LinphoneChatMessage *)bctbx_list_get_data(msg_list);
BC_ASSERT_EQUAL((int)linphone_chat_message_get_state(sent_msg), (int)LinphoneChatMessageStateNotDelivered, int, "%d");
}
bctbx_list_free_with_data(msg_list, (bctbx_list_free_func)linphone_chat_message_unref);
bc_free(send_filepath);
bc_free(initial_db);
bc_free(saved_db);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
test_t message_tests[] = {
TEST_NO_TAG("Text message", text_message),
TEST_NO_TAG("Text message within call dialog", text_message_within_call_dialog),
@ -2408,6 +2496,7 @@ test_t message_tests[] = {
TEST_ONE_TAG("Lime text message to non lime", lime_text_message_to_non_lime_mandatory_policy, "LIME"),
TEST_ONE_TAG("Lime text message to non lime with preferred policy", lime_text_message_to_non_lime_preferred_policy, "LIME"),
TEST_ONE_TAG("Lime text message to non lime with preferred policy 2", lime_text_message_to_non_lime_preferred_policy_2, "LIME"),
TEST_ONE_TAG("Lime text message without cache", lime_text_message_without_cache, "LIME"),
TEST_ONE_TAG("Lime transfer message", lime_transfer_message, "LIME"),
TEST_ONE_TAG("Lime transfer message 2", lime_transfer_message_2, "LIME"),
TEST_ONE_TAG("Lime transfer message 3", lime_transfer_message_3, "LIME"),
@ -2441,7 +2530,8 @@ test_t message_tests[] = {
TEST_ONE_TAG("Real Time Text copy paste", real_time_text_copy_paste, "RTT"),
TEST_NO_TAG("IM Encryption Engine custom headers", chat_message_custom_headers),
TEST_NO_TAG("Text message with custom content-type", text_message_with_custom_content_type),
TEST_ONE_TAG("Text message with custom content-type and lime", text_message_with_custom_content_type_and_lime, "LIME")
TEST_ONE_TAG("Text message with custom content-type and lime", text_message_with_custom_content_type_and_lime, "LIME"),
TEST_NO_TAG("Crash during file transfer", crash_during_file_transfer)
};
test_suite_t message_test_suite = {