diff --git a/CHANGELOG.md b/CHANGELOG.md index b157d8f689f7885c2166e09235fa2acd7de1e657..aae4dc2a03018f77d9865051aa4bd9f778e74e32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ This changelog file was started on October 2019. Previous changes were more or l - linphone_core_interpret_url() will unescape characters first if possible if only a username is given as input parameter. - linphone_chat_message_cancel_file_transfer() no longer deletes the file for outgoing messages. - magic search result created from filter now applies the international prefix of the default proxy config if possible. +- file transfer progress callback will be at most notified 100 times. ### Fixed - Internal refactoring of management of locally played tones, in order to fix race conditions. diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index a40173831db13200bb83094d29a3c38ca191f2e3..4e97ce70bc9c5843e1348958eefe24e8bd46102d 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -109,6 +109,11 @@ void FileTransferChatMessageModifier::fileTransferOnProgress ( if (!message) return; + size_t percentage = offset * 100 / total; + if (percentage <= lastNotifiedPercentage) { + return; + } + LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); @@ -120,6 +125,7 @@ void FileTransferChatMessageModifier::fileTransferOnProgress ( linphone_core_notify_file_transfer_progress_indication(message->getCore()->getCCore(), msg, content, offset, total); } _linphone_chat_message_notify_file_transfer_progress_indication(msg, content, offset, total); + lastNotifiedPercentage = percentage; } static int _chat_message_on_send_body ( @@ -520,6 +526,8 @@ int FileTransferChatMessageModifier::uploadFile (belle_sip_body_handler_t *bh) { currentFileContentToTransfer->setFilePath(message->getPrivate()->getFileTransferFilepath()); } + lastNotifiedPercentage = 0; + belle_http_request_listener_callbacks_t cbs = { 0 }; cbs.process_response = _chat_message_process_response_from_post_file; cbs.process_io_error = _chat_message_process_io_error_upload; @@ -1092,6 +1100,7 @@ bool FileTransferChatMessageModifier::downloadFile ( currentFileContentToTransfer->setFilePath(message->getPrivate()->getFileTransferFilepath()); } + lastNotifiedPercentage = 0; lInfo() << "Downloading file transfer content [" << fileTransferContent << "], removing it to keep only the file content [" << fileContent << "]"; belle_http_request_listener_callbacks_t cbs = { 0 }; diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.h b/src/chat/modifier/file-transfer-chat-message-modifier.h index 1e32a520034e996e0ea8bd3a4ce6948f401c9dd4..2725c900f4d006903643933e813c5132b216a5a2 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.h +++ b/src/chat/modifier/file-transfer-chat-message-modifier.h @@ -85,6 +85,8 @@ private: belle_http_request_listener_t *httpListener = nullptr; belle_http_provider_t *provider = nullptr; + size_t lastNotifiedPercentage = 0; + BackgroundTask bgTask; }; diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 73a1dadd97a5d393a711ed5421df87030ce28d07..39bd59d8b1cbdf026179f4880b28f9ac37a3bc25 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -243,33 +243,40 @@ bool MediaSessionPrivate::failure () { break; case SalReasonUnsupportedContent: /* This is for compatibility: linphone sent 415 because of SDP offer answer failure */ case SalReasonNotAcceptable: - lInfo() << "Outgoing CallSession [" << q << "] failed with SRTP and/or AVPF enabled"; - if ((state == CallSession::State::OutgoingInit) || (state == CallSession::State::OutgoingProgress) - || (state == CallSession::State::OutgoingRinging) /* Push notification case */ || (state == CallSession::State::OutgoingEarlyMedia)) { - for (int i = 0; i < localDesc->nb_streams; i++) { - if (!sal_stream_description_enabled(&localDesc->streams[i])) - continue; - if (getParams()->getMediaEncryption() == LinphoneMediaEncryptionSRTP) { - if (getParams()->avpfEnabled()) { - if (i == 0) - lInfo() << "Retrying CallSession [" << q << "] with SAVP"; - getParams()->enableAvpf(false); - restartInvite(); - return true; - } else if (!linphone_core_is_media_encryption_mandatory(q->getCore()->getCCore())) { + if ((state == CallSession::State::OutgoingInit) + || (state == CallSession::State::OutgoingProgress) + || (state == CallSession::State::OutgoingRinging) /* Push notification case */ + || (state == CallSession::State::OutgoingEarlyMedia)) { + bool mediaEncrptionSrtp = getParams()->getMediaEncryption() == LinphoneMediaEncryptionSRTP; + bool avpfEnabled = getParams()->avpfEnabled(); + if (mediaEncrptionSrtp || avpfEnabled) { + lInfo() << "Outgoing CallSession [" << q << "] failed with SRTP and/or AVPF enabled"; + + for (int i = 0; i < localDesc->nb_streams; i++) { + if (!sal_stream_description_enabled(&localDesc->streams[i])) + continue; + if (mediaEncrptionSrtp) { + if (avpfEnabled) { + if (i == 0) + lInfo() << "Retrying CallSession [" << q << "] with SAVP"; + getParams()->enableAvpf(false); + restartInvite(); + return true; + } else if (!linphone_core_is_media_encryption_mandatory(q->getCore()->getCCore())) { + if (i == 0) + lInfo() << "Retrying CallSession [" << q << "] with AVP"; + getParams()->setMediaEncryption(LinphoneMediaEncryptionNone); + memset(localDesc->streams[i].crypto, 0, sizeof(localDesc->streams[i].crypto)); + restartInvite(); + return true; + } + } else if (avpfEnabled) { if (i == 0) lInfo() << "Retrying CallSession [" << q << "] with AVP"; - getParams()->setMediaEncryption(LinphoneMediaEncryptionNone); - memset(localDesc->streams[i].crypto, 0, sizeof(localDesc->streams[i].crypto)); + getParams()->enableAvpf(false); restartInvite(); return true; } - } else if (getParams()->avpfEnabled()) { - if (i == 0) - lInfo() << "Retrying CallSession [" << q << "] with AVP"; - getParams()->enableAvpf(false); - restartInvite(); - return true; } } } diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 56cb659585c590f8a6fb446d7547741a9f95fc80..cf6b7207202475e1e92e01becc33d0dea6ff5094 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -245,6 +245,7 @@ typedef struct _stats { int number_of_LinphoneIsComposingActiveReceived; int number_of_LinphoneIsComposingIdleReceived; int progress_of_LinphoneFileTransfer; + int number_of_LinphoneFileTransfer; int number_of_LinphoneChatRoomConferenceJoined; int number_of_LinphoneChatRoomEphemeralTimerStarted; @@ -466,6 +467,7 @@ void _receive_file_plus_text(bctbx_list_t *coresList, LinphoneCoreManager *lcm, LinphoneBuffer * tester_memory_file_transfer_send(LinphoneChatMessage *message, LinphoneContent* content, size_t offset, size_t size); void file_transfer_progress_indication(LinphoneChatMessage *message, LinphoneContent* content, size_t offset, size_t total); +void file_transfer_progress_indication_2(LinphoneChatMessage *message, LinphoneContent* content, size_t offset, size_t total); void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room); void info_message_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg); void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url); diff --git a/tester/message_tester.c b/tester/message_tester.c index 09dbde00a1b523c8a0058c78047349b1c749624a..5fdaa6e32f4c4a29835ffb260f7b38330ef00cba 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -79,7 +79,7 @@ LinphoneChatMessage* create_message_from_sintel_trailer_legacy(LinphoneChatRoom return msg; } -LinphoneChatMessage* create_message_from_sintel_trailer(LinphoneChatRoom *chat_room) { +LinphoneChatMessage* _create_message_from_sintel_trailer(LinphoneChatRoom *chat_room, bool_t use_alt_file_transfer_progress_indication_cb) { FILE *file_to_send = NULL; LinphoneChatMessageCbs *cbs; LinphoneContent* content; @@ -103,7 +103,11 @@ LinphoneChatMessage* create_message_from_sintel_trailer(LinphoneChatRoom *chat_r cbs = linphone_factory_create_chat_message_cbs(linphone_factory_get()); linphone_chat_message_cbs_set_file_transfer_send_chunk(cbs, tester_file_transfer_send_2); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + if (use_alt_file_transfer_progress_indication_cb) { + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication_2); + } else { + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + } BC_ASSERT_PTR_NOT_NULL(linphone_content_get_user_data(content)); linphone_chat_message_add_callbacks(msg, cbs); linphone_chat_message_cbs_unref(cbs); @@ -113,6 +117,10 @@ LinphoneChatMessage* create_message_from_sintel_trailer(LinphoneChatRoom *chat_r return msg; } +LinphoneChatMessage* create_message_from_sintel_trailer(LinphoneChatRoom *chat_room) { + return _create_message_from_sintel_trailer(chat_room, FALSE); +} + LinphoneChatMessage* create_file_transfer_message_from_sintel_trailer(LinphoneChatRoom *chat_room) { FILE *file_to_send = NULL; LinphoneChatMessageCbs *cbs; @@ -1345,8 +1353,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_sintel_trailer(pauline_room); - msg2 = create_message_from_sintel_trailer(pauline_room); + msg = _create_message_from_sintel_trailer(pauline_room, FALSE); + msg2 = _create_message_from_sintel_trailer(pauline_room, TRUE); BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)), 0, unsigned int, "%u"); if (bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)) == 0) { @@ -1390,7 +1398,7 @@ static void file_transfer_2_messages_simultaneously(void) { cbs = linphone_factory_create_chat_message_cbs(linphone_factory_get()); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); - linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication_2); linphone_chat_message_add_callbacks(recvMsg2, cbs); linphone_chat_message_cbs_unref(cbs); linphone_chat_message_download_file(recvMsg2); diff --git a/tester/tester.c b/tester/tester.c index d06407364133ec6bbc773cc7f5090a5efb8cb47f..83739fc7dfa7cbc0de57399b07ca8e2128530eb2 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -2636,6 +2636,36 @@ void file_transfer_progress_indication(LinphoneChatMessage *msg, LinphoneContent stats *counters = get_stats(lc); char *address = linphone_address_as_string(linphone_chat_message_is_outgoing(msg) ? to_address : from_address); + if (progress == 0) { + counters->number_of_LinphoneFileTransfer = 0; + } + counters->number_of_LinphoneFileTransfer++; + + BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); + bctbx_message( + "File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", + progress, + linphone_chat_message_is_outgoing(msg) ? "sent" : "received", + linphone_content_get_type(content), + linphone_content_get_subtype(content), + linphone_chat_message_is_outgoing(msg) ? "to" : "from", + address + ); + counters->progress_of_LinphoneFileTransfer = progress; + if (progress == 100) { + counters->number_of_LinphoneFileTransferDownloadSuccessful++; + BC_ASSERT_LOWER(counters->number_of_LinphoneFileTransfer, 100, int, "%d"); + } + free(address); +} +void file_transfer_progress_indication_2(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t total) { + const LinphoneAddress *from_address = linphone_chat_message_get_from_address(msg); + const LinphoneAddress *to_address = linphone_chat_message_get_to_address(msg); + int progress = (int)((offset * 100)/total); + LinphoneCore *lc = linphone_chat_message_get_core(msg); + stats *counters = get_stats(lc); + char *address = linphone_address_as_string(linphone_chat_message_is_outgoing(msg) ? to_address : from_address); + BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); bctbx_message( "File transfer [%d%%] %s of type [%s/%s] %s [%s] \n",