diff --git a/coreapi/call_log.c b/coreapi/call_log.c index 47ff3edfb..86b85c712 100644 --- a/coreapi/call_log.c +++ b/coreapi/call_log.c @@ -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; diff --git a/coreapi/chat.c b/coreapi/chat.c index a8c60fa10..f67e0c9eb 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -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. */ } diff --git a/coreapi/chat_file_transfer.c b/coreapi/chat_file_transfer.c index 21567daee..d9dac9011 100644 --- a/coreapi/chat_file_transfer.c +++ b/coreapi/chat_file_transfer.c @@ -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 diff --git a/coreapi/friend.c b/coreapi/friend.c index bf25d9e53..c24902f2d 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -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); diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 1a4a17874..80cecee5c 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -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 diff --git a/coreapi/private.h b/coreapi/private.h index 410fca0cd..857461d48 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -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); diff --git a/tester/message_tester.c b/tester/message_tester.c index 057cc2b6a..824480a1d 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -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, ""); - 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, ""); - 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 = {