1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 16:03:27 +01:00

allow resuming of broken file transfers (needs testing)

This commit is contained in:
Jfreegman 2014-08-16 17:20:53 -04:00
parent ae83725cb6
commit b870679f2c
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
6 changed files with 71 additions and 5 deletions

View File

@ -176,6 +176,9 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *msg
} }
static void chat_resume_file_transfers(Tox *m, int fnum);
static void chat_stop_file_senders(int fnum);
static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status) static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
{ {
if (self->num != num) if (self->num != num)
@ -187,13 +190,15 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_
statusbar->is_online = true; statusbar->is_online = true;
Friends.list[num].is_typing = user_settings_->show_typing_other == SHOW_TYPING_ON Friends.list[num].is_typing = user_settings_->show_typing_other == SHOW_TYPING_ON
? tox_get_is_typing(m, num) : 0; ? tox_get_is_typing(m, num) : 0;
chat_resume_file_transfers(m, num);
} else { /* Friend goes offline */ } else { /* Friend goes offline */
statusbar->is_online = false; statusbar->is_online = false;
Friends.list[num].is_typing = 0; Friends.list[num].is_typing = 0;
if (self->chatwin->self_is_typing) if (self->chatwin->self_is_typing)
set_self_typingstatus(self, m, 0); set_self_typingstatus(self, m, 0);
chat_stop_file_senders(num);
} }
} }
@ -350,6 +355,36 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
"Incoming file: %s", filename ); "Incoming file: %s", filename );
} }
/* Stops active file senders for this friend. Call when a friend goes offline */
static void chat_stop_file_senders(int fnum)
{
int i;
for (i = 0; i < MAX_FILES; ++i) {
if (file_senders[i].active && file_senders[i].friendnum == fnum)
file_senders[i].noconnection = true;
}
}
/* Tries to resume broken file transfers. Call when a friend comes online */
static void chat_resume_file_transfers(Tox *m, int fnum)
{
if (Friends.list[fnum].active_file_receivers == 0)
return;
int i;
for (i = 0; i < MAX_FILES; ++i) {
if (Friends.list[fnum].file_receiver[i].active && !Friends.list[fnum].file_receiver[i].paused) {
uint8_t bytes_recv[sizeof(uint64_t)];
memcpy(bytes_recv, &Friends.list[fnum].file_receiver[i].bytes_recv, sizeof(uint64_t));
net_to_host(bytes_recv, sizeof(uint64_t));
int filenum = Friends.list[fnum].file_receiver[i].filenum;
tox_file_send_control(m, fnum, 1, filenum, TOX_FILECONTROL_RESUME_BROKEN, bytes_recv, sizeof(uint64_t));
}
}
}
/* set CTRL to -1 if we don't want to send a control signal. /* set CTRL to -1 if we don't want to send a control signal.
set msg to NULL if we don't want to display a message */ set msg to NULL if we don't want to display a message */
void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL) void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL)
@ -363,6 +398,7 @@ void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL)
fclose(file); fclose(file);
memset(&Friends.list[friendnum].file_receiver[filenum], 0, sizeof(struct FileReceiver)); memset(&Friends.list[friendnum].file_receiver[filenum], 0, sizeof(struct FileReceiver));
--Friends.list[friendnum].active_file_receivers;
} }
static void close_all_file_receivers(Tox *m, int friendnum) static void close_all_file_receivers(Tox *m, int friendnum)
@ -453,6 +489,26 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
self->name, "%s", msg); self->name, "%s", msg);
break; break;
case TOX_FILECONTROL_RESUME_BROKEN:
if (receive_send == 0)
break;
FILE *fp = file_senders[i].file;
if (fp == NULL)
break;
uint8_t tmp[sizeof(uint64_t)];
memcpy(tmp, &data, sizeof(uint64_t));
net_to_host(tmp, sizeof(uint64_t));
uint64_t datapos;
memcpy(&datapos, tmp, sizeof(uint64_t));
fseek(fp, datapos, SEEK_SET);
tox_file_send_control(m, num, 0, filenum, TOX_FILECONTROL_ACCEPT, 0, 0);
file_senders[i].noconnection = false;
break;
} }
if (msg[0]) if (msg[0])
@ -475,6 +531,7 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenu
} }
Friends.list[num].file_receiver[filenum].bps += length; Friends.list[num].file_receiver[filenum].bps += length;
Friends.list[num].file_receiver[filenum].bytes_recv += length;
double remain = (double) tox_file_data_remaining(m, num, filenum, 1); double remain = (double) tox_file_data_remaining(m, num, filenum, 1);
uint64_t curtime = get_unix_time(); uint64_t curtime = get_unix_time();

View File

@ -177,13 +177,15 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
if ((Friends.list[self->num].file_receiver[filenum].file = fopen(filename, "a")) == NULL) { if ((Friends.list[self->num].file_receiver[filenum].file = fopen(filename, "a")) == NULL) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Error writing to file."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Error writing to file.");
tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
} else {
Friends.list[self->num].file_receiver[filenum].active = true;
++Friends.list[self->num].active_file_receivers;
} }
} else { } else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed.");
} }
Friends.list[self->num].file_receiver[filenum].pending = false; Friends.list[self->num].file_receiver[filenum].pending = false;
Friends.list[self->num].file_receiver[filenum].active = true;
} }
void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])

View File

@ -44,13 +44,14 @@
#define DNS3_KEY_SIZE 32 #define DNS3_KEY_SIZE 32
#define MAX_DNS_REQST_SIZE 255 #define MAX_DNS_REQST_SIZE 255
#define NUM_DNS3_BACKUP_SERVERS 2 /* must correspond to number of items in dns3_servers array */
#define TOX_DNS3_TXT_PREFIX "v=tox3;id=" #define TOX_DNS3_TXT_PREFIX "v=tox3;id="
extern struct _Winthread Winthread; extern struct _Winthread Winthread;
extern struct _dns3_servers dns3_servers; extern struct _dns3_servers dns3_servers;
extern struct arg_opts arg_opts; extern struct arg_opts arg_opts;
#define NUM_DNS3_BACKUP_SERVERS 2
/* Hardcoded backup in case domain list is not loaded */ /* Hardcoded backup in case domain list is not loaded */
static struct dns3_server_backup { static struct dns3_server_backup {
const char *name; const char *name;

View File

@ -217,7 +217,9 @@ void do_file_senders(Tox *m)
continue; continue;
} }
send_file_data(self, m, i, friendnum, filenum, filename); if (file_senders[i].noconnection == false)
send_file_data(self, m, i, friendnum, filenum, filename);
file_senders[i].queue_pos = num_active_file_senders - 1; file_senders[i].queue_pos = num_active_file_senders - 1;
} }
} }

View File

@ -40,6 +40,7 @@ typedef struct {
ToxWindow *toxwin; ToxWindow *toxwin;
int32_t friendnum; int32_t friendnum;
bool active; bool active;
bool noconnection;
bool finished; bool finished;
int filenum; int filenum;
char nextpiece[FILE_PIECE_SIZE]; char nextpiece[FILE_PIECE_SIZE];

View File

@ -35,9 +35,11 @@ struct FileReceiver {
FILE *file; FILE *file;
bool pending; bool pending;
bool active; bool active;
bool paused;
uint64_t size; uint64_t size;
uint64_t bytes_recv;
double bps; double bps;
uint64_t last_progress; uint64_t last_progress; /* unix-time when we last updated progress */
uint32_t line_id; uint32_t line_id;
}; };
@ -64,6 +66,7 @@ typedef struct {
uint8_t status; uint8_t status;
struct LastOnline last_online; struct LastOnline last_online;
struct FileReceiver file_receiver[MAX_FILES]; struct FileReceiver file_receiver[MAX_FILES];
uint8_t active_file_receivers;
} ToxicFriend; } ToxicFriend;
typedef struct { typedef struct {