Commit 97050ac6 authored by johan's avatar johan

File Transfer: manage i/o error during file download from server

- note : not functional, test is bugged and commented. To be fixed.
parent ce24877b
......@@ -46,15 +46,35 @@ const char *multipart_boundary=MULTIPART_BOUNDARY;
static size_t linphone_chat_message_compute_filepart_header_size(const char *filename, const char *content_type) {
return strlen(FILEPART_HEADER_1)+strlen(filename)+strlen(FILEPART_HEADER_2)+strlen(content_type)+strlen(FILEPART_HEADER_3);
}
static void process_io_error(void *data, const belle_sip_io_error_event_t *event){
static void process_io_error_upload(void *data, const belle_sip_io_error_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
ms_error("I/O Error during file upload to %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
if (msg->cb) {
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
}
}
static void process_auth_requested_upload(void *data, belle_sip_auth_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
ms_error("Error during file upload : auth requested to connect %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
if (msg->cb) {
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
}
}
static void process_io_error_download(void *data, const belle_sip_io_error_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
ms_error("I/O Error during file upload or download to/from %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
ms_error("I/O Error during file download %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room);
if (msg->cb) {
msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->chat_room->lc);
}
}
static void process_auth_requested(void *data, belle_sip_auth_event_t *event){
static void process_auth_requested_download(void *data, belle_sip_auth_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
ms_error("Error during file upload or download : auth requested to connect %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
ms_error("Error during file download : auth requested to get %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room);
if (msg->cb) {
msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->chat_room->lc);
}
}
/**
......@@ -157,8 +177,8 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
belle_sip_free(content_type);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req),BELLE_SIP_BODY_HANDLER(bh));
cbs.process_response=linphone_chat_message_process_response_from_post_file;
cbs.process_io_error=process_io_error;
cbs.process_auth_requested=process_auth_requested;
cbs.process_io_error=process_io_error_upload;
cbs.process_auth_requested=process_auth_requested_upload;
l=belle_http_request_listener_create_from_callbacks(&cbs,msg);
msg->http_request=req; /* update the reference to the http request to be able to cancel it during upload */
belle_http_provider_send_request(msg->chat_room->lc->http_provider,req,l);
......@@ -343,8 +363,8 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
NULL,
NULL);
cbs.process_response=linphone_chat_message_process_response_from_post_file;
cbs.process_io_error=process_io_error;
cbs.process_auth_requested=process_auth_requested;
cbs.process_io_error=process_io_error_upload;
cbs.process_auth_requested=process_auth_requested_upload;
l=belle_http_request_listener_create_from_callbacks(&cbs,msg); /* give msg to listener to be able to start the actual file upload when server answer a 204 No content */
msg->http_request = req; /* keep a reference on the request to be able to cancel it */
belle_http_provider_send_request(cr->lc->http_provider,req,l);
......@@ -867,6 +887,7 @@ const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState
case LinphoneChatMessageStateInProgress:return "LinphoneChatMessageStateInProgress";
case LinphoneChatMessageStateDelivered:return "LinphoneChatMessageStateDelivered";
case LinphoneChatMessageStateNotDelivered:return "LinphoneChatMessageStateNotDelivered";
case LinphoneChatMessageStateFileTransferError:return "LinphoneChatMessageStateFileTransferError";
default: return "Unknown state";
}
......@@ -1048,8 +1069,9 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle
* Start the download of the file from remote server
*
* @param message #LinphoneChatMessage
* @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded
*/
void linphone_chat_message_start_file_download(LinphoneChatMessage *message) {
void linphone_chat_message_start_file_download(LinphoneChatMessage *message, LinphoneChatMessageStateChangedCb status_cb) {
belle_http_request_listener_callbacks_t cbs={0};
belle_http_request_listener_t *l;
belle_generic_uri_t *uri;
......@@ -1068,11 +1090,13 @@ void linphone_chat_message_start_file_download(LinphoneChatMessage *message) {
cbs.process_response_headers=linphone_chat_process_response_headers_from_get_file;
cbs.process_response=linphone_chat_process_response_from_get_file;
cbs.process_io_error=process_io_error;
cbs.process_auth_requested=process_auth_requested;
cbs.process_io_error=process_io_error_download;
cbs.process_auth_requested=process_auth_requested_download;
l=belle_http_request_listener_create_from_callbacks(&cbs, (void *)message);
belle_sip_object_data_set(BELLE_SIP_OBJECT(req),"message",(void *)message,NULL);
message->http_request = req; /* keep a reference on the request to be able to cancel the download */
message->cb = status_cb;
message->state = LinphoneChatMessageStateInProgress; /* start the download, status is In Progress */
belle_http_provider_send_request(message->chat_room->lc->http_provider,req,l);
}
......
......@@ -115,16 +115,6 @@ static void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message,
}
/*
* Call back called when a message is received
*/
static void message_received(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
const LinphoneContent *file_transfer_info = linphone_chat_message_get_file_transfer_information(msg);
printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, (long int)file_transfer_info->size);
linphone_chat_message_start_file_download(msg);
}
/*
* Call back to get delivery status of a message
* */
......@@ -136,6 +126,16 @@ static void linphone_file_transfer_state_changed(LinphoneChatMessage* msg,Linpho
free(to);
}
/*
* Call back called when a message is received
*/
static void message_received(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
const LinphoneContent *file_transfer_info = linphone_chat_message_get_file_transfer_information(msg);
printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, (long int)file_transfer_info->size);
linphone_chat_message_start_file_download(msg, linphone_file_transfer_state_changed);
}
LinphoneCore *lc;
int main(int argc, char *argv[]){
......
......@@ -1258,7 +1258,8 @@ typedef enum _LinphoneChatMessageState {
LinphoneChatMessageStateIdle, /**< Initial state */
LinphoneChatMessageStateInProgress, /**< Delivery in progress */
LinphoneChatMessageStateDelivered, /**< Message succesffully delivered an acknoleged by remote end point */
LinphoneChatMessageStateNotDelivered /**< Message was not delivered */
LinphoneChatMessageStateNotDelivered, /**< Message was not delivered */
LinphoneChatMessageStateFileTransferError /**< Message was received(and acknowledged) but cannot get file from server */
} LinphoneChatMessageState;
/**
......@@ -1331,7 +1332,7 @@ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to(const Linpho
LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
LINPHONE_PUBLIC const LinphoneContent* linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_start_file_download(LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb);
LINPHONE_PUBLIC void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage* msg);
LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data);
......
......@@ -124,7 +124,7 @@ void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *me
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);
stats* counters = get_stats(lc);
printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)progress
ms_message(" 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
......@@ -157,6 +157,9 @@ void liblinphone_tester_chat_message_state_change(LinphoneChatMessage* msg,Linph
case LinphoneChatMessageStateInProgress:
counters->number_of_LinphoneMessageInProgress++;
break;
case LinphoneChatMessageStateFileTransferError:
counters->number_of_LinphoneMessageNotDelivered++;
break;
default:
ms_error("Unexpected state [%s] for message [%p]",linphone_chat_message_state_to_string(state),msg);
}
......@@ -378,18 +381,19 @@ static void file_transfer_message(void) {
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_LinphoneMessageReceivedWithFile,1));
if (marie->stat.last_received_chat_message ) {
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message);
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
}
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void file_transfer_message_io_error(void) {
static void file_transfer_message_io_error_upload(void) {
int i;
char* to;
LinphoneChatRoom* chat_room;
......@@ -439,6 +443,67 @@ static void file_transfer_message_io_error(void) {
linphone_core_manager_destroy(pauline);
}
#ifdef TEST_IS_BUGGED_NO_CALL_TO_IO_ERROR_CALLBACK
static void file_transfer_message_io_error_download(void) {
int i;
char* to;
LinphoneChatRoom* chat_room;
LinphoneChatMessage* message;
LinphoneContent content;
const char* big_file_content="big file"; /* setting dummy file content to something */
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
/* setting dummy file content to something */
for (i=0;i<sizeof(big_file);i+=strlen(big_file_content))
memcpy(big_file+i, big_file_content, strlen(big_file_content));
big_file[0]=*"S";
big_file[sizeof(big_file)-1]=*"E";
/* Globally configure an http file transfer server. */
linphone_core_set_file_transfer_server(pauline->lc,"https://www.linphone.org:444/lft.php");
/* create a chatroom on pauline's side */
to = linphone_address_as_string(marie->identity);
chat_room = linphone_core_create_chat_room(pauline->lc,to);
/* create a file transfer message */
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";
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);
/* wait for marie to receive pauline's message */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
if (marie->stat.last_received_chat_message ) { /* get last message and use it to download file */
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
/* wait for file to be 50% downloaded */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
/* and simulate network error */
sal_set_recv_error(marie->lc->sal, -1);
}
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0);
sal_set_recv_error(marie->lc->sal, 0);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
#endif
static void file_transfer_message_upload_cancelled(void) {
int i;
char* to;
......@@ -529,16 +594,17 @@ static void file_transfer_message_download_cancelled(void) {
if (marie->stat.last_received_chat_message ) { /* get last message and use it to download file */
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message);
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
/* wait for file to be 50% downloaded */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
/* and cancel the transfer */
linphone_chat_room_cancel_file_transfer(marie->stat.last_received_chat_message);
}
//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(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
......@@ -776,7 +842,8 @@ test_t message_tests[] = {
{ "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 },
{ "File transfer message with io error", file_transfer_message_io_error },
{ "File transfer message with io error at upload", file_transfer_message_io_error_upload },
/* { "File transfer message with io error at download", file_transfer_message_io_error_download },*/
{ "File transfer message upload cancelled", file_transfer_message_upload_cancelled },
{ "File transfer message download cancelled", file_transfer_message_download_cancelled },
{ "Text message denied", text_message_denied },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment