From e98ad8e4a630b1e48b7851a64a2db3f85fad8c0d Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Sun, 8 Jun 2014 23:27:03 +0200 Subject: [PATCH] Add test for file transfer to liblinphone tester --- tester/liblinphone_tester.h | 3 + tester/message_tester.c | 116 +++++++++++++++++++++++++++++++++++- tester/tester.c | 3 + 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 5e5767bab..e7c77066b 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -208,6 +208,9 @@ void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf); void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message); void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message); +void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size); +void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size); +void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress); 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 8568492d4..e7b78d00b 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -35,18 +35,90 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess stats* counters; const char *text=linphone_chat_message_get_text(message); const char *external_body_url=linphone_chat_message_get_external_body_url(message); + const LinphoneContent *file_transfer_info=linphone_chat_message_get_file_transfer_information(message); + ms_message("Message from [%s] is [%s] , external URL [%s]",from?from:"" ,text?text:"" ,external_body_url?external_body_url:""); ms_free(from); counters = get_stats(lc); counters->number_of_LinphoneMessageReceived++; - if (linphone_chat_message_get_external_body_url(message)) { + if (file_transfer_info) { /* if we have a file transfer in RCS mode, start the download */ + linphone_chat_message_start_file_download(message); + } else if (linphone_chat_message_get_external_body_url(message)) { counters->number_of_LinphoneMessageExtBodyReceived++; CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url); } } +/** + * function invoked when a file transfer is received. + * */ +void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size){ + int file=-1; + if (!linphone_chat_message_get_user_data(message)) { + /*first chunk, creating file*/ + file = open("receive_file.dump",O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); + linphone_chat_message_set_user_data(message,(void*)(long)(0x00000000FFFFFFFF&file)); /*store fd for next chunks*/ + } else { + /*next chunk*/ + file = (int)((long)(linphone_chat_message_get_user_data(message))&0x00000000FFFFFFFF); + } + + if (size==0) { + linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message)); + linphone_chat_message_destroy(message); + stats* counters = get_stats(lc); + counters->number_of_LinphoneMessageExtBodyReceived++; + close(file); + } else { /* store content on a file*/ + write(file,buff,size); + } +} + +static char big_file [128000]; /* a buffer to simulate a big file for the file transfer message test */ + +/* + * function called when the file transfer is initiated. file content should be feed into object LinphoneContent + * */ +void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size){ + int offset=-1; + + if (!linphone_chat_message_get_user_data(message)) { + /*first chunk*/ + offset=0; + } else { + /*subsequent chunk*/ + offset = (int)((long)(linphone_chat_message_get_user_data(message))&0x00000000FFFFFFFF); + } + *size = MIN(*size,sizeof(big_file)-offset); /*updating content->size with minimun between remaining data and requested size*/ + + if (*size==0) { + /*end of file*/ + return; + } + memcpy(buff,big_file+offset,*size); + + /*store offset for next chunk*/ + linphone_chat_message_set_user_data(message,(void*)(offset+*size)); +} + +/** + * function invoked to report file transfer progress. + * */ +void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress) { + const LinphoneAddress* from_address = linphone_chat_message_get_from(message); + const LinphoneAddress* to_address = linphone_chat_message_get_to(message); + char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address); + printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)progress + ,(linphone_chat_message_is_outgoing(message)?"sent":"received") + , content->type + , content->subtype + ,(linphone_chat_message_is_outgoing(message)?"to":"from") + , address); + free(address); +} + void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { stats *counters = get_stats(lc); if (room->remote_is_composing == LinphoneIsComposingActive) { @@ -244,6 +316,47 @@ static void text_message_with_external_body(void) { linphone_core_manager_destroy(pauline); } +static void file_transfer_message(void) { + int i; + /* setting dummy file content to something */ + + const char* big_file_content="big file"; + for (i=0;ilc,"http://npasc.al/lft.php"); + + /* create a chatroom on pauline's side */ + char* to = linphone_address_as_string(marie->identity); + LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + + /* create a file transfer message */ + LinphoneContent content; + memset(&content,0,sizeof(content)); + content.type="text"; + content.subtype="plain"; + content.size=sizeof(big_file); /*total size to be transfered*/ + content.name = "bigfile.txt"; + LinphoneChatMessage* message = linphone_chat_room_create_file_transfer_message(chat_room, &content); + + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); + + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void text_message_with_send_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); @@ -379,6 +492,7 @@ test_t message_tests[] = { { "Text message with ack", text_message_with_ack }, { "Text message with send error", text_message_with_send_error }, { "Text message with external body", text_message_with_external_body }, + { "File transfer message", file_transfer_message }, { "Text message denied", text_message_denied }, { "Info message", info_message }, { "Info message with body", info_message_with_body }, diff --git a/tester/tester.c b/tester/tester.c index 3623073e4..3794d707f 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -196,6 +196,9 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f mgr->v_table.call_state_changed=call_state_changed; mgr->v_table.text_received=text_message_received; mgr->v_table.message_received=message_received; + mgr->v_table.file_transfer_received=file_transfer_received; + mgr->v_table.file_transfer_send=file_transfer_send; + mgr->v_table.file_transfer_progress_indication=file_transfer_progress_indication; mgr->v_table.is_composing_received=is_composing_received; mgr->v_table.new_subscription_requested=new_subscription_requested; mgr->v_table.notify_presence_received=notify_presence_received;